走进 .Net 单元测试

Intro

“不会写单元测试的程序员不是合格的程序员,不写单元测试的程序员不是优秀程序员。”

—— 一只想要成为一个优秀程序员的渣逼程序猿。

那么问题来了,什么是单元测试,如何做单元测试。

单元测试定义

按照维基百科上的说法,单元测试(Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。 程序单元是应用的最小可测试部件。在面向对象编程中,最小单元就是方法,包括基类、抽象类、或者派生类(子类)中的方法。 按照通俗的理解,一个单元测试判断某个特定场条件下某个特定方法的行为,如斐波那契数列算法,冒泡排序算法。

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。 对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义, 如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。 总的来说,单元就是人为规定的最小的被测功能模块。 单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

—— 百度百科 http://baike.baidu.com/view/106237.htm

进行单元测试的好处

  1. 它是一种验证行为

    程序中的每一项功能都是测试来验证它的正确性。

  2. 它是一种设计行为

    编写单元测试将使我们从调用者观察、思考。 特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,有利于程序的解耦和模块化。

  3. 它是一种编写文档的行为

    单元测试是一种无价的文档,它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,并且它保持最新,永远与代码同步。

  4. 它具有回归性

    自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地的快速运行测试。

  5. 高效

    自动化的单元测试节省了开发上调试BUG的时间,绝大多数BUG可以通过单元测试测试出来,并且可以减少测试人员的测试时间。有时候通过写单元测试能够更好的完善自己程序的逻辑,让程序变得更加美好。

    —— 单元测试的优点 http://jingyan.baidu.com/article/d713063522ab4e13fdf47533.html

单元测试的原则:

  • 可重复运行的
  • 持续长期有效,并且返回一致的结果
  • 在内存中运行,没有外部依赖组件(比如说真实的数据库,真实的文件存储等)
  • 快速返回结果
  • 一个测试方法只测试一个问题

VS单元测试 【MsTest】使用

VS单元测试的主要类:Assert、StringAssert、CollectionAssert,具体可参照 MSDN介绍

有些时候我们需要对测试的方法用到的数据或配置进行初始化,有几个特殊的测试方法。

如果需要针对测试中的所有虚拟用户迭代仅执行一次初始化操作,请使用 TestInitializeAttribute。

初始化方法的运行顺序如下:

  1. 用 AssemblyInitializeAttribute 标记的方法。
  2. 用 ClassInitializeAttribute 特性标记的方法。
  3. 用 TestInitializeAttribute 特性标记的方法。
  4. 用 TestMethodAttribute 特性标记的方法。

单元测试 使用示例

  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2.  
  3. namespace ConsoleApplication1Test
  4. {
  5. [TestClass]
  6. public class MainTest
  7. {
  8. #region TestFail
  9.  
  10. [TestMethod]
  11. public void TestFail0()
  12. {
  13. Assert.Fail();
  14. }
  15.  
  16. [TestMethod]
  17. public void TestFail1()
  18. {
  19. Assert.Fail("Test is fail");
  20. }
  21.  
  22. [TestMethod]
  23. public void TestFail2()
  24. {
  25. Assert.Fail("Test3 is fail,{0}", "hahaha");
  26. }
  27. #endregion
  28.  
  29. #region TestInconclusive 忽略
  30. [TestMethod]
  31. public void TestInconclusive0()
  32. {
  33. Assert.Inconclusive();
  34. }
  35.  
  36. [TestMethod]
  37. public void TestInconclusive1()
  38. {
  39. Assert.Inconclusive("Inconclusive");
  40. }
  41.  
  42. [TestMethod]
  43. public void TestInconclusive2()
  44. {
  45. Assert.Inconclusive("Inconclusive,{0}", "hehehe");
  46. }
  47. #endregion
  48.  
  49. #region LogicTest
  50.  
  51. #region Null
  52. [TestMethod]
  53. public void IsNullTest()
  54. {
  55. Assert.IsNull(null);
  56. }
  57.  
  58. [TestMethod]
  59. public void IsNotNullTest()
  60. {
  61. Assert.IsNotNull();
  62. }
  63. #endregion
  64.  
  65. #region True || False
  66. [TestMethod]
  67. public void IsTrueTest()
  68. {
  69. Assert.IsTrue( == );
  70. }
  71.  
  72. [TestMethod]
  73. public void IsFalseTest()
  74. {
  75. Assert.IsFalse( > );
  76. }
  77. #endregion
  78.  
  79. #region AreSame
  80. [TestMethod]
  81. public void AreSameTest()
  82. {
  83. //不要向 AreSame() 传递值类型的值,因为他们转换为 Object 后永久不会相等,值类型的值比较请使用 AreEqual()
  84. Assert.AreSame(, );
  85. }
  86.  
  87. [TestMethod]
  88. public void AreSameTest1()
  89. {
  90. object obj = new object(), obj1 = obj;
  91. Assert.AreSame(obj, obj1, "same");
  92. }
  93.  
  94. [TestMethod]
  95. public void StringAreSameTest0()
  96. {
  97. string str1 = "hello", str2 = "hello";
  98. Assert.AreSame(str1, str2);
  99. }
  100.  
  101. [TestMethod]
  102. public void StringAreSameTest1()
  103. {
  104. string str1 = "hello", str2 = "Hello";
  105. Assert.AreSame(str1, str2);
  106. }
  107.  
  108. [TestMethod]
  109. public void AreNotSameTest()
  110. {
  111. object obj = new object(), obj1 = new object();
  112. Assert.AreNotSame(obj, obj1);
  113. }
  114. #endregion
  115.  
  116. #region AreEqual
  117. [TestMethod]
  118. public void AreEqualTest()
  119. {
  120. Assert.AreEqual(, );
  121. }
  122.  
  123. [TestMethod]
  124. public void AreNotEqualTest()
  125. {
  126. Assert.AreNotEqual(, );
  127. }
  128.  
  129. [TestMethod]
  130. public void AreEqualTest1()
  131. {
  132. object obj = new object(), obj1 = obj;
  133. Assert.AreEqual(obj, obj1);
  134. }
  135.  
  136. [TestMethod]
  137. public void AreNotEqualTest1()
  138. {
  139. object obj = new object(), obj1 = new object();
  140. Assert.AreNotEqual(obj, obj1);
  141. }
  142.  
  143. [TestMethod]
  144. public void AreEqualTest2()
  145. {
  146. object obj = new object(), obj1 = new object();
  147. Assert.AreEqual(obj, obj1);
  148. // Assert.Equals()不用于断言,请使用 Assert.AreEquals() 或 Assert.AreNotEquals()
  149. //Assert.Equals(obj, obj1);
  150. }
  151.  
  152. [TestMethod]
  153. public void StringAreEqualTest0()
  154. {
  155. string str = "hello", str1 = "hello";
  156. Assert.AreEqual(str, str1);
  157. }
  158.  
  159. [TestMethod]
  160. public void StringAreEqualTest1()
  161. {
  162. string str = "hello", str1 = "Hello";
  163. Assert.AreEqual(str, str1, true);
  164. }
  165. #endregion
  166.  
  167. #region IsInstanceOfType
  168.  
  169. [TestMethod]
  170. public void IsInstanceOfTypeTest()
  171. {
  172. B b = new B();
  173. Assert.IsInstanceOfType(b, typeof(A));
  174. }
  175.  
  176. [TestMethod]
  177. public void IsNotInstanceOfTypeTest()
  178. {
  179. A a = new A();
  180. Assert.IsNotInstanceOfType(a, typeof(B));
  181. }
  182. #endregion
  183.  
  184. #endregion
  185.  
  186. #region 测试初始化和清理
  187. [AssemblyInitialize()]
  188. public static void AssemblyInit(TestContext context)
  189. {
  190. System.Console.WriteLine("AssemblyInit " + context.TestName);
  191. }
  192.  
  193. [ClassInitialize()]
  194. public static void ClassInit(TestContext context)
  195. {
  196. System.Console.WriteLine("ClassInit " + context.TestName);
  197. }
  198.  
  199. [TestInitialize]
  200. public void Initialize()
  201. {
  202. System.Console.WriteLine("TestMethodInit");
  203. }
  204.  
  205. [TestCleanup]
  206. public void Cleanup()
  207. {
  208. System.Console.WriteLine("TestMethodCleanup");
  209. }
  210.  
  211. [ClassCleanup]
  212. public static void ClassCleanup()
  213. {
  214. System.Console.WriteLine("ClassCleanup");
  215. }
  216.  
  217. [AssemblyCleanup]
  218. public static void AssemblyCleanup()
  219. {
  220. System.Console.WriteLine("AssemblyCleanup");
  221. }
  222. #endregion
  223. }
  224.  
  225. public class A { }
  226.  
  227. public class B : A { }
  228.  
  229. }

Ms Test单元测试

MsTest 和 Nunit区别

MS Test框架是Visual Studio自带的测试框架,可以通过新建一个Unit Test Project工程, 也可以建一个Class Libary,然后添加对Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll的引用。 然后就是创建测试用例,进行测试即可。

NUnit Test框架是一个xUnit家族种的第4个主打产品,完全由C#语言来编写,支持所有的.Net语言。 使用NUnit框架,我们需要下载安装包,安装后使用独立客户端进行使用。使用方法与MS Test类似

有一些是NUnit中的,但是MS Test框架中是没有的: - Assert.IsNaN - Assert.IsEmpty - Assert.IsNotEmpty - Assert.Greater - Assert.GreaterOrEqual - Assert.Less - Assert.LessOrEqual - Assert.IsAssignableFrom - Assert.IsNotAssignableFrom - Assert.Igore - CollectionAssert.IsEmpty - CollectionAssert.IsNotEmpty - StringAssert.AreEqualIgnoringCase - StringAssert.IsMatch - FileAssert.AreEqual - FileAssert.AreNotEqual

同时支持两种测试框架

可以通过宏判断来同时支持这两个框架,在测试前添加以下代码:

  1. #if !NUNIT
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3. using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;
  4. #else
  5. using NUnit.Framework;
  6. using TestClass = NUnit.Framework.TestFixtureAttribute;
  7. using TestMethod = NUnit.Framework.TestAttribute;
  8. using TestInitialize = NUnit.Framework.SetUpAttribute;
  9. using TestCleanup = NUnit.Framework.TearDownAttribute;
  10. using TestContext = System.Object;
  11. using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
  12. using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
  13. #endif

Nunit测试使用示例

  1. #region NUNIT
  2.  
  3. /// <summary>
  4. /// This test fixture attempts to exercise all the syntactic
  5. /// variations of Assert without getting into failures, errors
  6. /// or corner cases.Thus, some of the tests may be duplicated
  7. /// in other fixtures.
  8. ///
  9. /// Each test performs the same operations using the classic
  10. /// syntax(if available) and the new syntax in both the
  11. /// helper-based and inherited forms.
  12. ///
  13. /// This Fixture will eventually be duplicated in other
  14. /// supported languages.
  15. /// </summary>
  16. [TestFixture]
  17. public class AssertSyntaxTests : AssertionHelper
  18. {
  19. #region Simple Constraint Tests
  20. [Test]
  21. public void IsNull()
  22. {
  23. object nada = null;
  24.  
  25. // Classic syntax
  26. Assert.IsNull(nada);
  27.  
  28. // Constraint Syntax
  29. Assert.That(nada, Is.Null);
  30.  
  31. // Inherited syntax
  32. Expect(nada, Null);
  33. }
  34.  
  35. [Test]
  36. public void IsNotNull()
  37. {
  38. // Classic syntax
  39. Assert.IsNotNull();
  40.  
  41. // Constraint Syntax
  42. Assert.That(, Is.Not.Null);
  43.  
  44. // Inherited syntax
  45. Expect(, Not.Null);
  46. }
  47.  
  48. [Test]
  49. public void IsTrue()
  50. {
  51. // Classic syntax
  52. Assert.IsTrue( + == );
  53.  
  54. // Constraint Syntax
  55. Assert.That( + == , Is.True);
  56. Assert.That( + == );
  57.  
  58. // Inherited syntax
  59. Expect( + == , True);
  60. Expect( + == );
  61. }
  62.  
  63. [Test]
  64. public void IsFalse()
  65. {
  66. // Classic syntax
  67. Assert.IsFalse( + == );
  68.  
  69. // Constraint Syntax
  70. Assert.That( + == , Is.False);
  71.  
  72. // Inherited syntax
  73. Expect( + == , False);
  74. }
  75.  
  76. [Test]
  77. public void IsNaN()
  78. {
  79. double d = double.NaN;
  80. float f = float.NaN;
  81.  
  82. // Classic syntax
  83. Assert.IsNaN(d);
  84. Assert.IsNaN(f);
  85.  
  86. // Constraint Syntax
  87. Assert.That(d, Is.NaN);
  88. Assert.That(f, Is.NaN);
  89.  
  90. // Inherited syntax
  91. Expect(d, NaN);
  92. Expect(f, NaN);
  93. }
  94.  
  95. [Test]
  96. public void EmptyStringTests()
  97. {
  98. // Classic syntax
  99. Assert.IsEmpty("");
  100. Assert.IsNotEmpty("Hello!");
  101.  
  102. // Constraint Syntax
  103. Assert.That("", Is.Empty);
  104. Assert.That("Hello!", Is.Not.Empty);
  105.  
  106. // Inherited syntax
  107. Expect("", Empty);
  108. Expect("Hello!", Not.Empty);
  109. }
  110.  
  111. [Test]
  112. public void EmptyCollectionTests()
  113. {
  114. // Classic syntax
  115. Assert.IsEmpty(new bool[]);
  116. Assert.IsNotEmpty(new int[] { , , });
  117.  
  118. // Constraint Syntax
  119. Assert.That(new bool[], Is.Empty);
  120. Assert.That(new int[] { , , }, Is.Not.Empty);
  121.  
  122. // Inherited syntax
  123. Expect(new bool[], Empty);
  124. Expect(new int[] { , , }, Not.Empty);
  125. }
  126. #endregion
  127.  
  128. #region TypeConstraint Tests
  129. [Test]
  130. public void ExactTypeTests()
  131. {
  132. // Classic syntax workarounds
  133. Assert.AreEqual(typeof(string), "Hello".GetType());
  134. Assert.AreEqual("System.String", "Hello".GetType().FullName);
  135. Assert.AreNotEqual(typeof(int), "Hello".GetType());
  136. Assert.AreNotEqual("System.Int32", "Hello".GetType().FullName);
  137.  
  138. // Constraint Syntax
  139. Assert.That("Hello", Is.TypeOf(typeof(string)));
  140. Assert.That("Hello", Is.Not.TypeOf(typeof(int)));
  141.  
  142. // Inherited syntax
  143. Expect("Hello", TypeOf(typeof(string)));
  144. Expect("Hello", Not.TypeOf(typeof(int)));
  145. }
  146.  
  147. [Test]
  148. public void InstanceOfTests()
  149. {
  150. // Classic syntax
  151. Assert.IsInstanceOf(typeof(string), "Hello");
  152. Assert.IsNotInstanceOf(typeof(string), );
  153.  
  154. // Constraint Syntax
  155. Assert.That("Hello", Is.InstanceOf(typeof(string)));
  156. Assert.That(, Is.Not.InstanceOf(typeof(string)));
  157.  
  158. // Inherited syntax
  159. Expect("Hello", InstanceOf(typeof(string)));
  160. Expect(, Not.InstanceOf(typeof(string)));
  161. }
  162.  
  163. [Test]
  164. public void AssignableFromTypeTests()
  165. {
  166. // Classic syntax
  167. Assert.IsAssignableFrom(typeof(string), "Hello");
  168. Assert.IsNotAssignableFrom(typeof(string), );
  169.  
  170. // Constraint Syntax
  171. Assert.That("Hello", Is.AssignableFrom(typeof(string)));
  172. Assert.That(, Is.Not.AssignableFrom(typeof(string)));
  173.  
  174. // Inherited syntax
  175. Expect("Hello", AssignableFrom(typeof(string)));
  176. Expect(, Not.AssignableFrom(typeof(string)));
  177. }
  178. #endregion
  179.  
  180. #region StringConstraint Tests
  181. [Test]
  182. public void SubstringTests()
  183. {
  184. string phrase = "Hello World!";
  185. string[] array = new string[] { "abc", "bad", "dba" };
  186.  
  187. // Classic Syntax
  188. StringAssert.Contains("World", phrase);
  189.  
  190. // Constraint Syntax
  191. Assert.That(phrase, Does.Contain("World"));
  192. // Only available using new syntax
  193. Assert.That(phrase, Does.Not.Contain("goodbye"));
  194. Assert.That(phrase, Does.Contain("WORLD").IgnoreCase);
  195. Assert.That(phrase, Does.Not.Contain("BYE").IgnoreCase);
  196. Assert.That(array, Is.All.Contains("b"));
  197.  
  198. // Inherited syntax
  199. Expect(phrase, Contains("World"));
  200. // Only available using new syntax
  201. Expect(phrase, Not.Contains("goodbye"));
  202. Expect(phrase, Contains("WORLD").IgnoreCase);
  203. Expect(phrase, Not.Contains("BYE").IgnoreCase);
  204. Expect(array, All.Contains("b"));
  205. }
  206.  
  207. [Test]
  208. public void StartsWithTests()
  209. {
  210. string phrase = "Hello World!";
  211. string[] greetings = new string[] { "Hello!", "Hi!", "Hola!" };
  212.  
  213. // Classic syntax
  214. StringAssert.StartsWith("Hello", phrase);
  215.  
  216. // Constraint Syntax
  217. Assert.That(phrase, Does.StartWith("Hello"));
  218. // Only available using new syntax
  219. Assert.That(phrase, Does.Not.StartWith("Hi!"));
  220. Assert.That(phrase, Does.StartWith("HeLLo").IgnoreCase);
  221. Assert.That(phrase, Does.Not.StartWith("HI").IgnoreCase);
  222. Assert.That(greetings, Is.All.StartsWith("h").IgnoreCase);
  223.  
  224. // Inherited syntax
  225. Expect(phrase, StartsWith("Hello"));
  226. // Only available using new syntax
  227. Expect(phrase, Not.StartsWith("Hi!"));
  228. Expect(phrase, StartsWith("HeLLo").IgnoreCase);
  229. Expect(phrase, Not.StartsWith("HI").IgnoreCase);
  230. Expect(greetings, All.StartsWith("h").IgnoreCase);
  231. }
  232.  
  233. [Test]
  234. public void EndsWithTests()
  235. {
  236. string phrase = "Hello World!";
  237. string[] greetings = new string[] { "Hello!", "Hi!", "Hola!" };
  238.  
  239. // Classic Syntax
  240. StringAssert.EndsWith("!", phrase);
  241.  
  242. // Constraint Syntax
  243. Assert.That(phrase, Does.EndWith("!"));
  244. // Only available using new syntax
  245. Assert.That(phrase, Does.Not.EndWith("?"));
  246. Assert.That(phrase, Does.EndWith("WORLD!").IgnoreCase);
  247. Assert.That(greetings, Is.All.EndsWith("!"));
  248.  
  249. // Inherited syntax
  250. Expect(phrase, EndsWith("!"));
  251. // Only available using new syntax
  252. Expect(phrase, Not.EndsWith("?"));
  253. Expect(phrase, EndsWith("WORLD!").IgnoreCase);
  254. Expect(greetings, All.EndsWith("!"));
  255. }
  256.  
  257. [Test]
  258. public void EqualIgnoringCaseTests()
  259. {
  260. string phrase = "Hello World!";
  261.  
  262. // Classic syntax
  263. StringAssert.AreEqualIgnoringCase("hello world!", phrase);
  264.  
  265. // Constraint Syntax
  266. Assert.That(phrase, Is.EqualTo("hello world!").IgnoreCase);
  267. //Only available using new syntax
  268. Assert.That(phrase, Is.Not.EqualTo("goodbye world!").IgnoreCase);
  269. Assert.That(new string[] { "Hello", "World" },
  270. Is.EqualTo(new object[] { "HELLO", "WORLD" }).IgnoreCase);
  271. Assert.That(new string[] { "HELLO", "Hello", "hello" },
  272. Is.All.EqualTo("hello").IgnoreCase);
  273.  
  274. // Inherited syntax
  275. Expect(phrase, EqualTo("hello world!").IgnoreCase);
  276. //Only available using new syntax
  277. Expect(phrase, Not.EqualTo("goodbye world!").IgnoreCase);
  278. Expect(new string[] { "Hello", "World" },
  279. EqualTo(new object[] { "HELLO", "WORLD" }).IgnoreCase);
  280. Expect(new string[] { "HELLO", "Hello", "hello" },
  281. All.EqualTo("hello").IgnoreCase);
  282. }
  283.  
  284. [Test]
  285. public void RegularExpressionTests()
  286. {
  287. string phrase = "Now is the time for all good men to come to the aid of their country.";
  288. string[] quotes = new string[] { "Never say never", "It's never too late", "Nevermore!" };
  289.  
  290. // Classic syntax
  291. StringAssert.IsMatch("all good men", phrase);
  292. StringAssert.IsMatch("Now.*come", phrase);
  293.  
  294. // Constraint Syntax
  295. Assert.That(phrase, Does.Match("all good men"));
  296. Assert.That(phrase, Does.Match("Now.*come"));
  297. // Only available using new syntax
  298. Assert.That(phrase, Does.Not.Match("all.*men.*good"));
  299. Assert.That(phrase, Does.Match("ALL").IgnoreCase);
  300. Assert.That(quotes, Is.All.Matches("never").IgnoreCase);
  301.  
  302. // Inherited syntax
  303. Expect(phrase, Matches("all good men"));
  304. Expect(phrase, Matches("Now.*come"));
  305. // Only available using new syntax
  306. Expect(phrase, Not.Matches("all.*men.*good"));
  307. Expect(phrase, Matches("ALL").IgnoreCase);
  308. Expect(quotes, All.Matches("never").IgnoreCase);
  309. }
  310. #endregion
  311.  
  312. #region Equality Tests
  313. [Test]
  314. public void EqualityTests()
  315. {
  316. int[] i3 = new int[] { , , };
  317. double[] d3 = new double[] { 1.0, 2.0, 3.0 };
  318. int[] iunequal = new int[] { , , };
  319.  
  320. // Classic Syntax
  321. Assert.AreEqual(, + );
  322. Assert.AreEqual(i3, d3);
  323. Assert.AreNotEqual(, + );
  324. Assert.AreNotEqual(i3, iunequal);
  325.  
  326. // Constraint Syntax
  327. Assert.That( + , Is.EqualTo());
  328. Assert.That( + == );
  329. Assert.That(i3, Is.EqualTo(d3));
  330. Assert.That( + , Is.Not.EqualTo());
  331. Assert.That(i3, Is.Not.EqualTo(iunequal));
  332.  
  333. // Inherited syntax
  334. Expect( + , EqualTo());
  335. Expect( + == );
  336. Expect(i3, EqualTo(d3));
  337. Expect( + , Not.EqualTo());
  338. Expect(i3, Not.EqualTo(iunequal));
  339. }
  340.  
  341. [Test]
  342. public void EqualityTestsWithTolerance()
  343. {
  344. // CLassic syntax
  345. Assert.AreEqual(5.0d, 4.99d, 0.05d);
  346. Assert.AreEqual(5.0f, 4.99f, 0.05f);
  347.  
  348. // Constraint Syntax
  349. Assert.That(4.99d, Is.EqualTo(5.0d).Within(0.05d));
  350. Assert.That(4.0d, Is.Not.EqualTo(5.0d).Within(0.5d));
  351. Assert.That(4.99f, Is.EqualTo(5.0f).Within(0.05f));
  352. Assert.That(4.99m, Is.EqualTo(5.0m).Within(0.05m));
  353. Assert.That(3999999999u, Is.EqualTo(4000000000u).Within(5u));
  354. Assert.That(, Is.EqualTo().Within());
  355. Assert.That(4999999999L, Is.EqualTo(5000000000L).Within(5L));
  356. Assert.That(5999999999ul, Is.EqualTo(6000000000ul).Within(5ul));
  357.  
  358. // Inherited syntax
  359. Expect(4.99d, EqualTo(5.0d).Within(0.05d));
  360. Expect(4.0d, Not.EqualTo(5.0d).Within(0.5d));
  361. Expect(4.99f, EqualTo(5.0f).Within(0.05f));
  362. Expect(4.99m, EqualTo(5.0m).Within(0.05m));
  363. Expect(499u, EqualTo(500u).Within(5u));
  364. Expect(, EqualTo().Within());
  365. Expect(4999999999L, EqualTo(5000000000L).Within(5L));
  366. Expect(5999999999ul, EqualTo(6000000000ul).Within(5ul));
  367. }
  368.  
  369. [Test]
  370. public void EqualityTestsWithTolerance_MixedFloatAndDouble()
  371. {
  372. // Bug Fix 1743844
  373. Assert.That(2.20492d, Is.EqualTo(2.2d).Within(0.01f),
  374. "Double actual, Double expected, Single tolerance");
  375. Assert.That(2.20492d, Is.EqualTo(2.2f).Within(0.01d),
  376. "Double actual, Single expected, Double tolerance");
  377. Assert.That(2.20492d, Is.EqualTo(2.2f).Within(0.01f),
  378. "Double actual, Single expected, Single tolerance");
  379. Assert.That(2.20492f, Is.EqualTo(2.2f).Within(0.01d),
  380. "Single actual, Single expected, Double tolerance");
  381. Assert.That(2.20492f, Is.EqualTo(2.2d).Within(0.01d),
  382. "Single actual, Double expected, Double tolerance");
  383. Assert.That(2.20492f, Is.EqualTo(2.2d).Within(0.01f),
  384. "Single actual, Double expected, Single tolerance");
  385. }
  386.  
  387. [Test]
  388. public void EqualityTestsWithTolerance_MixingTypesGenerally()
  389. {
  390. // Extending tolerance to all numeric types
  391. Assert.That(202d, Is.EqualTo(200d).Within(),
  392. "Double actual, Double expected, int tolerance");
  393. Assert.That(4.87m, Is.EqualTo().Within(.),
  394. "Decimal actual, int expected, Double tolerance");
  395. Assert.That(4.87m, Is.EqualTo(5ul).Within(),
  396. "Decimal actual, ulong expected, int tolerance");
  397. Assert.That(, Is.EqualTo().Within(),
  398. "int actual, int expected, int tolerance");
  399. Assert.That(487u, Is.EqualTo().Within(),
  400. "uint actual, int expected, int tolerance");
  401. Assert.That(487L, Is.EqualTo().Within(),
  402. "long actual, int expected, int tolerance");
  403. Assert.That(487ul, Is.EqualTo().Within(),
  404. "ulong actual, int expected, int tolerance");
  405. }
  406. #endregion
  407.  
  408. #region Comparison Tests
  409. [Test]
  410. public void ComparisonTests()
  411. {
  412. // Classic Syntax
  413. Assert.Greater(, );
  414. Assert.GreaterOrEqual(, );
  415. Assert.GreaterOrEqual(, );
  416.  
  417. // Constraint Syntax
  418. Assert.That(, Is.GreaterThan());
  419. Assert.That(, Is.GreaterThanOrEqualTo());
  420. Assert.That(, Is.AtLeast());
  421. Assert.That(, Is.GreaterThanOrEqualTo());
  422. Assert.That(, Is.AtLeast());
  423.  
  424. // Inherited syntax
  425. Expect(, GreaterThan());
  426. Expect(, GreaterThanOrEqualTo());
  427. Expect(, AtLeast());
  428. Expect(, GreaterThanOrEqualTo());
  429. Expect(, AtLeast());
  430.  
  431. // Classic syntax
  432. Assert.Less(, );
  433. Assert.LessOrEqual(, );
  434. Assert.LessOrEqual(, );
  435.  
  436. // Constraint Syntax
  437. Assert.That(, Is.LessThan());
  438. Assert.That(, Is.LessThanOrEqualTo());
  439. Assert.That(, Is.AtMost());
  440. Assert.That(, Is.LessThanOrEqualTo());
  441. Assert.That(, Is.AtMost());
  442.  
  443. // Inherited syntax
  444. Expect(, LessThan());
  445. Expect(, LessThanOrEqualTo());
  446. Expect(, AtMost());
  447. Expect(, LessThanOrEqualTo());
  448. Expect(, AtMost());
  449. }
  450. #endregion
  451.  
  452. #region Collection Tests
  453. [Test]
  454. public void AllItemsTests()
  455. {
  456. object[] ints = new object[] { , , , };
  457. object[] doubles = new object[] { 0.99, 2.1, 3.0, 4.05 };
  458. object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" };
  459.  
  460. // Classic syntax
  461. CollectionAssert.AllItemsAreNotNull(ints);
  462. CollectionAssert.AllItemsAreInstancesOfType(ints, typeof(int));
  463. CollectionAssert.AllItemsAreInstancesOfType(strings, typeof(string));
  464. CollectionAssert.AllItemsAreUnique(ints);
  465.  
  466. // Constraint Syntax
  467. Assert.That(ints, Is.All.Not.Null);
  468. Assert.That(ints, Has.None.Null);
  469. Assert.That(ints, Is.All.InstanceOf(typeof(int)));
  470. Assert.That(ints, Has.All.InstanceOf(typeof(int)));
  471. Assert.That(strings, Is.All.InstanceOf(typeof(string)));
  472. Assert.That(strings, Has.All.InstanceOf(typeof(string)));
  473. Assert.That(ints, Is.Unique);
  474. // Only available using new syntax
  475. Assert.That(strings, Is.Not.Unique);
  476. Assert.That(ints, Is.All.GreaterThan());
  477. Assert.That(ints, Has.All.GreaterThan());
  478. Assert.That(ints, Has.None.LessThanOrEqualTo());
  479. Assert.That(strings, Is.All.Contains("a"));
  480. Assert.That(strings, Has.All.Contains("a"));
  481. Assert.That(strings, Has.Some.StartsWith("ba"));
  482. Assert.That(strings, Has.Some.Property("Length").EqualTo());
  483. Assert.That(strings, Has.Some.StartsWith("BA").IgnoreCase);
  484. Assert.That(doubles, Has.Some.EqualTo(1.0).Within(.));
  485.  
  486. // Inherited syntax
  487. Expect(ints, All.Not.Null);
  488. Expect(ints, None.Null);
  489. Expect(ints, All.InstanceOf(typeof(int)));
  490. Expect(strings, All.InstanceOf(typeof(string)));
  491. Expect(ints, Unique);
  492. // Only available using new syntax
  493. Expect(strings, Not.Unique);
  494. Expect(ints, All.GreaterThan());
  495. Expect(ints, None.LessThanOrEqualTo());
  496. Expect(strings, All.Contains("a"));
  497. Expect(strings, Some.StartsWith("ba"));
  498. Expect(strings, Some.StartsWith("BA").IgnoreCase);
  499. Expect(doubles, Some.EqualTo(1.0).Within(.));
  500. }
  501.  
  502. [Test]
  503. public void SomeItemTests()
  504. {
  505. object[] mixed = new object[] { , , "", null, "four", };
  506. object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" };
  507.  
  508. // Not available using the classic syntax
  509.  
  510. // Constraint Syntax
  511. Assert.That(mixed, Has.Some.Null);
  512. Assert.That(mixed, Has.Some.InstanceOf(typeof(int)));
  513. Assert.That(mixed, Has.Some.InstanceOf(typeof(string)));
  514. Assert.That(strings, Has.Some.StartsWith("ba"));
  515. Assert.That(strings, Has.Some.Not.StartsWith("ba"));
  516.  
  517. // Inherited syntax
  518. Expect(mixed, Some.Null);
  519. Expect(mixed, Some.InstanceOf(typeof(int)));
  520. Expect(mixed, Some.InstanceOf(typeof(string)));
  521. Expect(strings, Some.StartsWith("ba"));
  522. Expect(strings, Some.Not.StartsWith("ba"));
  523. }
  524.  
  525. [Test]
  526. public void NoItemTests()
  527. {
  528. object[] ints = new object[] { , , , , };
  529. object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" };
  530.  
  531. // Not available using the classic syntax
  532.  
  533. // Constraint Syntax
  534. Assert.That(ints, Has.None.Null);
  535. Assert.That(ints, Has.None.InstanceOf(typeof(string)));
  536. Assert.That(ints, Has.None.GreaterThan());
  537. Assert.That(strings, Has.None.StartsWith("qu"));
  538.  
  539. // Inherited syntax
  540. Expect(ints, None.Null);
  541. Expect(ints, None.InstanceOf(typeof(string)));
  542. Expect(ints, None.GreaterThan());
  543. Expect(strings, None.StartsWith("qu"));
  544. }
  545.  
  546. [Test]
  547. public void CollectionContainsTests()
  548. {
  549. int[] iarray = new int[] { , , };
  550. string[] sarray = new string[] { "a", "b", "c" };
  551.  
  552. // Classic syntax
  553. Assert.Contains(, iarray);
  554. Assert.Contains("b", sarray);
  555. CollectionAssert.Contains(iarray, );
  556. CollectionAssert.Contains(sarray, "b");
  557. CollectionAssert.DoesNotContain(sarray, "x");
  558. // Showing that Contains uses NUnit equality
  559. CollectionAssert.Contains(iarray, 1.0d);
  560.  
  561. // Constraint Syntax
  562. Assert.That(iarray, Has.Member());
  563. Assert.That(sarray, Has.Member("b"));
  564. Assert.That(sarray, Has.No.Member("x"));
  565. // Showing that Contains uses NUnit equality
  566. Assert.That(iarray, Has.Member(1.0d));
  567.  
  568. // Only available using the new syntax
  569. // Note that EqualTo and SameAs do NOT give
  570. // identical results to Contains because
  571. // Contains uses Object.Equals()
  572. Assert.That(iarray, Has.Some.EqualTo());
  573. Assert.That(iarray, Has.Member());
  574. Assert.That(sarray, Has.Some.EqualTo("b"));
  575. Assert.That(sarray, Has.None.EqualTo("x"));
  576. Assert.That(iarray, Has.None.SameAs(1.0d));
  577. Assert.That(iarray, Has.All.LessThan());
  578. Assert.That(sarray, Has.All.Length.EqualTo());
  579. Assert.That(sarray, Has.None.Property("Length").GreaterThan());
  580.  
  581. // Inherited syntax
  582. Expect(iarray, Contains());
  583. Expect(sarray, Contains("b"));
  584. Expect(sarray, Not.Contains("x"));
  585.  
  586. // Only available using new syntax
  587. // Note that EqualTo and SameAs do NOT give
  588. // identical results to Contains because
  589. // Contains uses Object.Equals()
  590. Expect(iarray, Some.EqualTo());
  591. Expect(sarray, Some.EqualTo("b"));
  592. Expect(sarray, None.EqualTo("x"));
  593. Expect(iarray, All.LessThan());
  594. Expect(sarray, All.Length.EqualTo());
  595. Expect(sarray, None.Property("Length").GreaterThan());
  596. }
  597.  
  598. [Test]
  599. public void CollectionEquivalenceTests()
  600. {
  601. int[] ints1to5 = new int[] { , , , , };
  602. int[] twothrees = new int[] { , , , , , };
  603. int[] twofours = new int[] { , , , , , };
  604.  
  605. // Classic syntax
  606. CollectionAssert.AreEquivalent(new int[] { , , , , }, ints1to5);
  607. CollectionAssert.AreNotEquivalent(new int[] { , , , , }, ints1to5);
  608. CollectionAssert.AreNotEquivalent(new int[] { , , , }, ints1to5);
  609. CollectionAssert.AreNotEquivalent(new int[] { , , , , , , }, ints1to5);
  610. CollectionAssert.AreNotEquivalent(twothrees, twofours);
  611.  
  612. // Constraint Syntax
  613. Assert.That(new int[] { , , , , }, Is.EquivalentTo(ints1to5));
  614. Assert.That(new int[] { , , , , }, Is.Not.EquivalentTo(ints1to5));
  615. Assert.That(new int[] { , , , }, Is.Not.EquivalentTo(ints1to5));
  616. Assert.That(new int[] { , , , , , , }, Is.Not.EquivalentTo(ints1to5));
  617.  
  618. // Inherited syntax
  619. Expect(new int[] { , , , , }, EquivalentTo(ints1to5));
  620. Expect(new int[] { , , , , }, Not.EquivalentTo(ints1to5));
  621. Expect(new int[] { , , , }, Not.EquivalentTo(ints1to5));
  622. Expect(new int[] { , , , , , , }, Not.EquivalentTo(ints1to5));
  623. }
  624.  
  625. [Test]
  626. public void SubsetTests()
  627. {
  628. int[] ints1to5 = new int[] { , , , , };
  629.  
  630. // Classic syntax
  631. CollectionAssert.IsSubsetOf(new int[] { , , }, ints1to5);
  632. CollectionAssert.IsSubsetOf(new int[] { , , , , }, ints1to5);
  633. CollectionAssert.IsNotSubsetOf(new int[] { , , }, ints1to5);
  634. CollectionAssert.IsNotSubsetOf(new int[] { , , , , }, ints1to5);
  635.  
  636. // Constraint Syntax
  637. Assert.That(new int[] { , , }, Is.SubsetOf(ints1to5));
  638. Assert.That(new int[] { , , , , }, Is.SubsetOf(ints1to5));
  639. Assert.That(new int[] { , , }, Is.Not.SubsetOf(ints1to5));
  640.  
  641. // Inherited syntax
  642. Expect(new int[] { , , }, SubsetOf(ints1to5));
  643. Expect(new int[] { , , , , }, SubsetOf(ints1to5));
  644. Expect(new int[] { , , }, Not.SubsetOf(ints1to5));
  645. }
  646. #endregion
  647.  
  648. #region Property Tests
  649. [Test]
  650. public void PropertyTests()
  651. {
  652. string[] array = { "abc", "bca", "xyz", "qrs" };
  653. string[] array2 = { "a", "ab", "abc" };
  654. ArrayList list = new ArrayList(array);
  655.  
  656. // Not available using the classic syntax
  657.  
  658. // Constraint Syntax
  659. Assert.That(list, Has.Property("Count"));
  660. Assert.That(list, Has.No.Property("Length"));
  661.  
  662. Assert.That("Hello", Has.Length.EqualTo());
  663. Assert.That("Hello", Has.Length.LessThan());
  664. Assert.That("Hello", Has.Property("Length").EqualTo());
  665. Assert.That("Hello", Has.Property("Length").GreaterThan());
  666.  
  667. Assert.That(array, Has.Property("Length").EqualTo());
  668. Assert.That(array, Has.Length.EqualTo());
  669. Assert.That(array, Has.Property("Length").LessThan());
  670.  
  671. Assert.That(array, Has.All.Property("Length").EqualTo());
  672. Assert.That(array, Has.All.Length.EqualTo());
  673. Assert.That(array, Is.All.Length.EqualTo());
  674. Assert.That(array, Has.All.Property("Length").EqualTo());
  675. Assert.That(array, Is.All.Property("Length").EqualTo());
  676.  
  677. Assert.That(array2, Has.Some.Property("Length").EqualTo());
  678. Assert.That(array2, Has.Some.Length.EqualTo());
  679. Assert.That(array2, Has.Some.Property("Length").GreaterThan());
  680.  
  681. Assert.That(array2, Is.Not.Property("Length").EqualTo());
  682. Assert.That(array2, Is.Not.Length.EqualTo());
  683. Assert.That(array2, Has.No.Property("Length").GreaterThan());
  684.  
  685. Assert.That(List.Map(array2).Property("Length"), Is.EqualTo(new int[] { , , }));
  686. Assert.That(List.Map(array2).Property("Length"), Is.EquivalentTo(new int[] { , , }));
  687. Assert.That(List.Map(array2).Property("Length"), Is.SubsetOf(new int[] { , , , , }));
  688. Assert.That(List.Map(array2).Property("Length"), Is.Unique);
  689.  
  690. Assert.That(list, Has.Count.EqualTo());
  691.  
  692. // Inherited syntax
  693. Expect(list, Property("Count"));
  694. Expect(list, Not.Property("Nada"));
  695.  
  696. Expect("Hello", Length.EqualTo());
  697. Expect("Hello", Property("Length").EqualTo());
  698. Expect("Hello", Property("Length").GreaterThan());
  699.  
  700. Expect(array, Property("Length").EqualTo());
  701. Expect(array, Length.EqualTo());
  702. Expect(array, Property("Length").LessThan());
  703.  
  704. Expect(array, All.Length.EqualTo());
  705. Expect(array, All.Property("Length").EqualTo());
  706.  
  707. Expect(array2, Some.Property("Length").EqualTo());
  708. Expect(array2, Some.Length.EqualTo());
  709. Expect(array2, Some.Property("Length").GreaterThan());
  710.  
  711. Expect(array2, None.Property("Length").EqualTo());
  712. Expect(array2, None.Length.EqualTo());
  713. Expect(array2, None.Property("Length").GreaterThan());
  714.  
  715. Expect(Map(array2).Property("Length"), EqualTo(new int[] { , , }));
  716. Expect(Map(array2).Property("Length"), EquivalentTo(new int[] { , , }));
  717. Expect(Map(array2).Property("Length"), SubsetOf(new int[] { , , , , }));
  718. Expect(Map(array2).Property("Length"), Unique);
  719.  
  720. Expect(list, Count.EqualTo());
  721.  
  722. }
  723. #endregion
  724.  
  725. #region Not Tests
  726. [Test]
  727. public void NotTests()
  728. {
  729. // Not available using the classic syntax
  730.  
  731. // Constraint Syntax
  732. Assert.That(, Is.Not.Null);
  733. Assert.That(, Is.Not.True);
  734. Assert.That(, Is.Not.False);
  735. Assert.That(2.5, Is.Not.NaN);
  736. Assert.That( + , Is.Not.EqualTo());
  737. Assert.That( + , Is.Not.Not.EqualTo());
  738. Assert.That( + , Is.Not.Not.Not.EqualTo());
  739.  
  740. // Inherited syntax
  741. Expect(, Not.Null);
  742. Expect(, Not.True);
  743. Expect(, Not.False);
  744. Expect(2.5, Not.NaN);
  745. Expect( + , Not.EqualTo());
  746. Expect( + , Not.Not.EqualTo());
  747. Expect( + , Not.Not.Not.EqualTo());
  748. }
  749. #endregion
  750.  
  751. #region Operator Tests
  752. [Test]
  753. public void NotOperator()
  754. {
  755. // The ! operator is only available in the new syntax
  756. Assert.That(, !Is.Null);
  757. // Inherited syntax
  758. Expect(, !Null);
  759. }
  760.  
  761. [Test]
  762. public void AndOperator()
  763. {
  764. // The & operator is only available in the new syntax
  765. Assert.That(, Is.GreaterThan() & Is.LessThan());
  766. // Inherited syntax
  767. Expect(, GreaterThan() & LessThan());
  768. }
  769.  
  770. [Test]
  771. public void OrOperator()
  772. {
  773. // The | operator is only available in the new syntax
  774. Assert.That(, Is.LessThan() | Is.GreaterThan());
  775. Expect(, LessThan() | GreaterThan());
  776. }
  777.  
  778. [Test]
  779. public void ComplexTests()
  780. {
  781. Assert.That(, Is.Not.Null & Is.Not.LessThan() & Is.Not.GreaterThan());
  782. Expect(, Not.Null & Not.LessThan() & Not.GreaterThan());
  783.  
  784. Assert.That(, !Is.Null & !Is.LessThan() & !Is.GreaterThan());
  785. Expect(, !Null & !LessThan() & !GreaterThan());
  786.  
  787. // No longer works at all under 3.0
  788. // TODO: Evaluate why we wanted to use null in this setting in the first place
  789. #if false
  790. // TODO: Remove #if when mono compiler can handle null
  791. #if MONO
  792. Constraint x = null;
  793. Assert.That(, !x & !Is.LessThan() & !Is.GreaterThan());
  794. Expect(, !x & !LessThan() & !GreaterThan());
  795. #else
  796. Assert.That(, !(Constraint)null & !Is.LessThan() & !Is.GreaterThan());
  797. Expect(, !(Constraint)null & !LessThan() & !GreaterThan());
  798. #endif
  799. #endif
  800. }
  801. #endregion
  802.  
  803. #region Invalid Code Tests
  804. // This method contains assertions that should not compile
  805. // You can check by uncommenting it.
  806. //public void WillNotCompile()
  807. //{
  808. // Assert.That(42, Is.Not);
  809. // Assert.That(42, Is.All);
  810. // Assert.That(42, Is.Null.Not);
  811. // Assert.That(42, Is.Not.Null.GreaterThan(10));
  812. // Assert.That(42, Is.GreaterThan(10).LessThan(99));
  813.  
  814. // object[] c = new object[0];
  815. // Assert.That(c, Is.Null.All);
  816. // Assert.That(c, Is.Not.All);
  817. // Assert.That(c, Is.All.Not);
  818. //}
  819. #endregion
  820. }
  821.  
  822. #endregion

Nunit 单元测试

单元测试参考资料

走进 .Net 单元测试的更多相关文章

  1. 走进JavaWeb技术世界11:单元测试框架Junit

    JUnit你不知道的那些事儿 转自 老刘 码农翻身 2016-02-24 话说有一次Eric Gamma 坐飞机的时候偶遇Kent Beck(对,就是极限编程和TDD的发起人) ,  两位大牛见面寒暄 ...

  2. c#中单元测试

    从走进.net后发现每天有写不完的代码,有做不完的测试...人感觉都已经机械,我们需要认清自己调整好心态,问下自己是否真的喜欢编程.我的答案当然也就是我爱编码,编码给我带来了许多欢乐,每天都给我体验小 ...

  3. Intellij idea添加单元测试工具

    1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...

  4. Python的单元测试(二)

    title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...

  5. Python的单元测试(一)

    title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...

  6. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  7. [C#] 走进异步编程的世界 - 开始接触 async/await

    走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $&qu ...

  8. [C#] 走进 LINQ 的世界

    走进 LINQ 的世界 序 在此之前曾发表过三篇关于 LINQ 的随笔: 进阶:<LINQ 标准查询操作概述>(强烈推荐) 技巧:<Linq To Objects - 如何操作字符串 ...

  9. 【NLP】前戏:一起走进条件随机场(一)

    前戏:一起走进条件随机场 作者:白宁超 2016年8月2日13:59:46 [摘要]:条件随机场用于序列标注,数据分割等自然语言处理中,表现出很好的效果.在中文分词.中文人名识别和歧义消解等任务中都有 ...

随机推荐

  1. SSIS Destination 组件使用Fast-Load mode出错

    查看一个Package的历史Message 数据,发现 DataFlow Task 经常出错,错误信息的Description是: Description: "While reading c ...

  2. javascript动画系列第五篇——模拟滚动条

    × 目录 [1]原理介绍 [2]数字加减 [3]元素尺寸[4]内容滚动 前面的话 当元素内容溢出元素尺寸范围时,会出现滚动条.但由于滚动条在各浏览器下表现不同,兼容性不好.所以,模拟滚动条也是很常见的 ...

  3. 【原创】开源Math.NET基础数学类库使用(06)直接求解线性方程组

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  4. ASP.NET MVC之Unobtrusive Ajax(五)

    前言 这一节我们来讲讲Unobtrusive中的Ajax提交,大部分情况下我们是利用JQuery来进行Ajax请求,当然利用JQuery来进行表单Ajax请求也不例外,但是相对于Unobtrusive ...

  5. 生成Kindle可读的mobi和PDF电子书

    购买kindle之后,自然欣喜万分,不来自于工具本身,而来自于发现自己能够静下心来阅读长篇和复杂的文字了,可喜可贺.更重要的是,kindle减轻了我眼睛的莫大的压力.但马上就出现几个问题: 不是所有的 ...

  6. 如何搭建Percona XtraDB Cluster集群

    一.环境准备 主机IP                     主机名               操作系统版本     PXC 192.168.244.146     node1           ...

  7. 条形码的应用三-----------从Excel文件中读取条形码

    条形码的应用三------从Excel文件中读取条形码 介绍 上一篇文章,我向大家展示了生成多个条形码并存储到Excel文件中的一个方法.后来我又有了个想法:既然条码插入到excel中了,我可不可以从 ...

  8. C/C++:提升_指针的指针和指针的引用

    C/C++:提升_指针的指针和指针的引用 写在前面 今天在使用指针的时候我发现了一个自己的错误.

  9. Oracle 11g安装GI后,运行roothas.pl脚本报错libcap.so.1找不到

    环境:RHEL6.4 + Oracle 11.2.0.3问题:需求是文件系统迁移到ASM,在安装GI后,运行roothas.pl脚本报错 1.运行root.sh后,按提示运行roothas.pl报错 ...

  10. mousewheel事件的兼容方法

    在垂直方向上滚动页面时,会触发mousewheel事件,这个事件会在任何元素上触发,最终都会冒泡到document(IE8)或window(IE9+及其他主流现代浏览器)对象. 在给元素指定mouse ...