你的位置:首页 > ASP.net教程

[ASP.net教程]走进 .Net 单元测试


走进 .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(1); 62     }  63     #endregion 64  65     #region True || False 66     [TestMethod] 67     public void IsTrueTest() 68     { 69       Assert.IsTrue(1 == 1); 70     } 71  72     [TestMethod] 73     public void IsFalseTest() 74     { 75       Assert.IsFalse(1 > 2); 76     }  77     #endregion 78  79     #region AreSame 80     [TestMethod] 81     public void AreSameTest() 82     { 83       //不要向 AreSame() 传递值类型的值,因为他们转换为 Object 后永久不会相等,值类型的值比较请使用 AreEqual() 84       Assert.AreSame(1, 1); 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     #endregion115 116     #region AreEqual117     [TestMethod]118     public void AreEqualTest()119     {120       Assert.AreEqual(1, 1);121     }122 123     [TestMethod]124     public void AreNotEqualTest()125     {126       Assert.AreNotEqual(1, 2);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     #endregion166 167     #region IsInstanceOfType168 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     #endregion183 184     #endregion185 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     #endregion223   }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(42); 40  41       // Constraint Syntax 42       Assert.That(42, Is.Not.Null); 43  44       // Inherited syntax 45       Expect(42, Not.Null); 46     } 47  48     [Test] 49     public void IsTrue() 50     { 51       // Classic syntax 52       Assert.IsTrue(2 + 2 == 4); 53  54       // Constraint Syntax 55       Assert.That(2 + 2 == 4, Is.True); 56       Assert.That(2 + 2 == 4); 57  58       // Inherited syntax 59       Expect(2 + 2 == 4, True); 60       Expect(2 + 2 == 4); 61     } 62  63     [Test] 64     public void IsFalse() 65     { 66       // Classic syntax 67       Assert.IsFalse(2 + 2 == 5); 68  69       // Constraint Syntax 70       Assert.That(2 + 2 == 5, Is.False); 71  72       // Inherited syntax 73       Expect(2 + 2 == 5, 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 Syntax103       Assert.That("", Is.Empty);104       Assert.That("Hello!", Is.Not.Empty);105 106       // Inherited syntax107       Expect("", Empty);108       Expect("Hello!", Not.Empty);109     }110 111     [Test]112     public void EmptyCollectionTests()113     {114       // Classic syntax115       Assert.IsEmpty(new bool[0]);116       Assert.IsNotEmpty(new int[] { 1, 2, 3 });117 118       // Constraint Syntax119       Assert.That(new bool[0], Is.Empty);120       Assert.That(new int[] { 1, 2, 3 }, Is.Not.Empty);121 122       // Inherited syntax123       Expect(new bool[0], Empty);124       Expect(new int[] { 1, 2, 3 }, Not.Empty);125     }126     #endregion127 128     #region TypeConstraint Tests129     [Test]130     public void ExactTypeTests()131     {132       // Classic syntax workarounds133       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 Syntax139       Assert.That("Hello", Is.TypeOf(typeof(string)));140       Assert.That("Hello", Is.Not.TypeOf(typeof(int)));141 142       // Inherited syntax143       Expect("Hello", TypeOf(typeof(string)));144       Expect("Hello", Not.TypeOf(typeof(int)));145     }146 147     [Test]148     public void InstanceOfTests()149     {150       // Classic syntax151       Assert.IsInstanceOf(typeof(string), "Hello");152       Assert.IsNotInstanceOf(typeof(string), 5);153 154       // Constraint Syntax155       Assert.That("Hello", Is.InstanceOf(typeof(string)));156       Assert.That(5, Is.Not.InstanceOf(typeof(string)));157 158       // Inherited syntax159       Expect("Hello", InstanceOf(typeof(string)));160       Expect(5, Not.InstanceOf(typeof(string)));161     }162 163     [Test]164     public void AssignableFromTypeTests()165     {166       // Classic syntax167       Assert.IsAssignableFrom(typeof(string), "Hello");168       Assert.IsNotAssignableFrom(typeof(string), 5);169 170       // Constraint Syntax171       Assert.That("Hello", Is.AssignableFrom(typeof(string)));172       Assert.That(5, Is.Not.AssignableFrom(typeof(string)));173 174       // Inherited syntax175       Expect("Hello", AssignableFrom(typeof(string)));176       Expect(5, Not.AssignableFrom(typeof(string)));177     }178     #endregion179 180     #region StringConstraint Tests181     [Test]182     public void SubstringTests()183     {184       string phrase = "Hello World!";185       string[] array = new string[] { "abc", "bad", "dba" };186 187       // Classic Syntax188       StringAssert.Contains("World", phrase);189 190       // Constraint Syntax191       Assert.That(phrase, Does.Contain("World"));192       // Only available using new syntax193       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 syntax199       Expect(phrase, Contains("World"));200       // Only available using new syntax201       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 syntax214       StringAssert.StartsWith("Hello", phrase);215 216       // Constraint Syntax217       Assert.That(phrase, Does.StartWith("Hello"));218       // Only available using new syntax219       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 syntax225       Expect(phrase, StartsWith("Hello"));226       // Only available using new syntax227       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 Syntax240       StringAssert.EndsWith("!", phrase);241 242       // Constraint Syntax243       Assert.That(phrase, Does.EndWith("!"));244       // Only available using new syntax245       Assert.That(phrase, Does.Not.EndWith("?"));246       Assert.That(phrase, Does.EndWith("WORLD!").IgnoreCase);247       Assert.That(greetings, Is.All.EndsWith("!"));248 249       // Inherited syntax250       Expect(phrase, EndsWith("!"));251       // Only available using new syntax252       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 syntax263       StringAssert.AreEqualIgnoringCase("hello world!", phrase);264 265       // Constraint Syntax266       Assert.That(phrase, Is.EqualTo("hello world!").IgnoreCase);267       //Only available using new syntax268       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 syntax275       Expect(phrase, EqualTo("hello world!").IgnoreCase);276       //Only available using new syntax277       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 syntax291       StringAssert.IsMatch("all good men", phrase);292       StringAssert.IsMatch("Now.*come", phrase);293 294       // Constraint Syntax295       Assert.That(phrase, Does.Match("all good men"));296       Assert.That(phrase, Does.Match("Now.*come"));297       // Only available using new syntax298       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 syntax303       Expect(phrase, Matches("all good men"));304       Expect(phrase, Matches("Now.*come"));305       // Only available using new syntax306       Expect(phrase, Not.Matches("all.*men.*good"));307       Expect(phrase, Matches("ALL").IgnoreCase);308       Expect(quotes, All.Matches("never").IgnoreCase);309     }310     #endregion311 312     #region Equality Tests313     [Test]314     public void EqualityTests()315     {316       int[] i3 = new int[] { 1, 2, 3 };317       double[] d3 = new double[] { 1.0, 2.0, 3.0 };318       int[] iunequal = new int[] { 1, 3, 2 };319 320       // Classic Syntax321       Assert.AreEqual(4, 2 + 2);322       Assert.AreEqual(i3, d3);323       Assert.AreNotEqual(5, 2 + 2);324       Assert.AreNotEqual(i3, iunequal);325 326       // Constraint Syntax327       Assert.That(2 + 2, Is.EqualTo(4));328       Assert.That(2 + 2 == 4);329       Assert.That(i3, Is.EqualTo(d3));330       Assert.That(2 + 2, Is.Not.EqualTo(5));331       Assert.That(i3, Is.Not.EqualTo(iunequal));332 333       // Inherited syntax334       Expect(2 + 2, EqualTo(4));335       Expect(2 + 2 == 4);336       Expect(i3, EqualTo(d3));337       Expect(2 + 2, Not.EqualTo(5));338       Expect(i3, Not.EqualTo(iunequal));339     }340 341     [Test]342     public void EqualityTestsWithTolerance()343     {344       // CLassic syntax345       Assert.AreEqual(5.0d, 4.99d, 0.05d);346       Assert.AreEqual(5.0f, 4.99f, 0.05f);347 348       // Constraint Syntax349       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(499, Is.EqualTo(500).Within(5));355       Assert.That(4999999999L, Is.EqualTo(5000000000L).Within(5L));356       Assert.That(5999999999ul, Is.EqualTo(6000000000ul).Within(5ul));357 358       // Inherited syntax359       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(499, EqualTo(500).Within(5));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 1743844373       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 types391       Assert.That(202d, Is.EqualTo(200d).Within(2),392         "Double actual, Double expected, int tolerance");393       Assert.That(4.87m, Is.EqualTo(5).Within(.25),394         "Decimal actual, int expected, Double tolerance");395       Assert.That(4.87m, Is.EqualTo(5ul).Within(1),396         "Decimal actual, ulong expected, int tolerance");397       Assert.That(487, Is.EqualTo(500).Within(25),398         "int actual, int expected, int tolerance");399       Assert.That(487u, Is.EqualTo(500).Within(25),400         "uint actual, int expected, int tolerance");401       Assert.That(487L, Is.EqualTo(500).Within(25),402         "long actual, int expected, int tolerance");403       Assert.That(487ul, Is.EqualTo(500).Within(25),404         "ulong actual, int expected, int tolerance");405     }406     #endregion407 408     #region Comparison Tests409     [Test]410     public void ComparisonTests()411     {412       // Classic Syntax413       Assert.Greater(7, 3);414       Assert.GreaterOrEqual(7, 3);415       Assert.GreaterOrEqual(7, 7);416 417       // Constraint Syntax418       Assert.That(7, Is.GreaterThan(3));419       Assert.That(7, Is.GreaterThanOrEqualTo(3));420       Assert.That(7, Is.AtLeast(3));421       Assert.That(7, Is.GreaterThanOrEqualTo(7));422       Assert.That(7, Is.AtLeast(7));423 424       // Inherited syntax425       Expect(7, GreaterThan(3));426       Expect(7, GreaterThanOrEqualTo(3));427       Expect(7, AtLeast(3));428       Expect(7, GreaterThanOrEqualTo(7));429       Expect(7, AtLeast(7));430 431       // Classic syntax432       Assert.Less(3, 7);433       Assert.LessOrEqual(3, 7);434       Assert.LessOrEqual(3, 3);435 436       // Constraint Syntax437       Assert.That(3, Is.LessThan(7));438       Assert.That(3, Is.LessThanOrEqualTo(7));439       Assert.That(3, Is.AtMost(7));440       Assert.That(3, Is.LessThanOrEqualTo(3));441       Assert.That(3, Is.AtMost(3));442 443       // Inherited syntax444       Expect(3, LessThan(7));445       Expect(3, LessThanOrEqualTo(7));446       Expect(3, AtMost(7));447       Expect(3, LessThanOrEqualTo(3));448       Expect(3, AtMost(3));449     }450     #endregion451 452     #region Collection Tests453     [Test]454     public void AllItemsTests()455     {456       object[] ints = new object[] { 1, 2, 3, 4 };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 syntax461       CollectionAssert.AllItemsAreNotNull(ints);462       CollectionAssert.AllItemsAreInstancesOfType(ints, typeof(int));463       CollectionAssert.AllItemsAreInstancesOfType(strings, typeof(string));464       CollectionAssert.AllItemsAreUnique(ints);465 466       // Constraint Syntax467       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 syntax475       Assert.That(strings, Is.Not.Unique);476       Assert.That(ints, Is.All.GreaterThan(0));477       Assert.That(ints, Has.All.GreaterThan(0));478       Assert.That(ints, Has.None.LessThanOrEqualTo(0));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(3));483       Assert.That(strings, Has.Some.StartsWith("BA").IgnoreCase);484       Assert.That(doubles, Has.Some.EqualTo(1.0).Within(.05));485 486       // Inherited syntax487       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 syntax493       Expect(strings, Not.Unique);494       Expect(ints, All.GreaterThan(0));495       Expect(ints, None.LessThanOrEqualTo(0));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(.05));500     }501 502     [Test]503     public void SomeItemTests()504     {505       object[] mixed = new object[] { 1, 2, "3", null, "four", 100 };506       object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" };507 508       // Not available using the classic syntax509 510       // Constraint Syntax511       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 syntax518       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[] { 1, 2, 3, 4, 5 };529       object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" };530 531       // Not available using the classic syntax532 533       // Constraint Syntax534       Assert.That(ints, Has.None.Null);535       Assert.That(ints, Has.None.InstanceOf(typeof(string)));536       Assert.That(ints, Has.None.GreaterThan(99));537       Assert.That(strings, Has.None.StartsWith("qu"));538 539       // Inherited syntax540       Expect(ints, None.Null);541       Expect(ints, None.InstanceOf(typeof(string)));542       Expect(ints, None.GreaterThan(99));543       Expect(strings, None.StartsWith("qu"));544     }545 546     [Test]547     public void CollectionContainsTests()548     {549       int[] iarray = new int[] { 1, 2, 3 };550       string[] sarray = new string[] { "a", "b", "c" };551 552       // Classic syntax553       Assert.Contains(3, iarray);554       Assert.Contains("b", sarray);555       CollectionAssert.Contains(iarray, 3);556       CollectionAssert.Contains(sarray, "b");557       CollectionAssert.DoesNotContain(sarray, "x");558       // Showing that Contains uses NUnit equality559       CollectionAssert.Contains(iarray, 1.0d);560 561       // Constraint Syntax562       Assert.That(iarray, Has.Member(3));563       Assert.That(sarray, Has.Member("b"));564       Assert.That(sarray, Has.No.Member("x"));565       // Showing that Contains uses NUnit equality566       Assert.That(iarray, Has.Member(1.0d));567 568       // Only available using the new syntax569       // Note that EqualTo and SameAs do NOT give570       // identical results to Contains because 571       // Contains uses Object.Equals()572       Assert.That(iarray, Has.Some.EqualTo(3));573       Assert.That(iarray, Has.Member(3));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(10));578       Assert.That(sarray, Has.All.Length.EqualTo(1));579       Assert.That(sarray, Has.None.Property("Length").GreaterThan(3));580 581       // Inherited syntax582       Expect(iarray, Contains(3));583       Expect(sarray, Contains("b"));584       Expect(sarray, Not.Contains("x"));585 586       // Only available using new syntax587       // Note that EqualTo and SameAs do NOT give588       // identical results to Contains because 589       // Contains uses Object.Equals()590       Expect(iarray, Some.EqualTo(3));591       Expect(sarray, Some.EqualTo("b"));592       Expect(sarray, None.EqualTo("x"));593       Expect(iarray, All.LessThan(10));594       Expect(sarray, All.Length.EqualTo(1));595       Expect(sarray, None.Property("Length").GreaterThan(3));596     }597 598     [Test]599     public void CollectionEquivalenceTests()600     {601       int[] ints1to5 = new int[] { 1, 2, 3, 4, 5 };602       int[] twothrees = new int[] { 1, 2, 3, 3, 4, 5 };603       int[] twofours = new int[] { 1, 2, 3, 4, 4, 5 };604 605       // Classic syntax606       CollectionAssert.AreEquivalent(new int[] { 2, 1, 4, 3, 5 }, ints1to5);607       CollectionAssert.AreNotEquivalent(new int[] { 2, 2, 4, 3, 5 }, ints1to5);608       CollectionAssert.AreNotEquivalent(new int[] { 2, 4, 3, 5 }, ints1to5);609       CollectionAssert.AreNotEquivalent(new int[] { 2, 2, 1, 1, 4, 3, 5 }, ints1to5);610       CollectionAssert.AreNotEquivalent(twothrees, twofours);611 612       // Constraint Syntax613       Assert.That(new int[] { 2, 1, 4, 3, 5 }, Is.EquivalentTo(ints1to5));614       Assert.That(new int[] { 2, 2, 4, 3, 5 }, Is.Not.EquivalentTo(ints1to5));615       Assert.That(new int[] { 2, 4, 3, 5 }, Is.Not.EquivalentTo(ints1to5));616       Assert.That(new int[] { 2, 2, 1, 1, 4, 3, 5 }, Is.Not.EquivalentTo(ints1to5));617 618       // Inherited syntax619       Expect(new int[] { 2, 1, 4, 3, 5 }, EquivalentTo(ints1to5));620       Expect(new int[] { 2, 2, 4, 3, 5 }, Not.EquivalentTo(ints1to5));621       Expect(new int[] { 2, 4, 3, 5 }, Not.EquivalentTo(ints1to5));622       Expect(new int[] { 2, 2, 1, 1, 4, 3, 5 }, Not.EquivalentTo(ints1to5));623     }624 625     [Test]626     public void SubsetTests()627     {628       int[] ints1to5 = new int[] { 1, 2, 3, 4, 5 };629 630       // Classic syntax631       CollectionAssert.IsSubsetOf(new int[] { 1, 3, 5 }, ints1to5);632       CollectionAssert.IsSubsetOf(new int[] { 1, 2, 3, 4, 5 }, ints1to5);633       CollectionAssert.IsNotSubsetOf(new int[] { 2, 4, 6 }, ints1to5);634       CollectionAssert.IsNotSubsetOf(new int[] { 1, 2, 2, 2, 5 }, ints1to5);635 636       // Constraint Syntax637       Assert.That(new int[] { 1, 3, 5 }, Is.SubsetOf(ints1to5));638       Assert.That(new int[] { 1, 2, 3, 4, 5 }, Is.SubsetOf(ints1to5));639       Assert.That(new int[] { 2, 4, 6 }, Is.Not.SubsetOf(ints1to5));640 641       // Inherited syntax642       Expect(new int[] { 1, 3, 5 }, SubsetOf(ints1to5));643       Expect(new int[] { 1, 2, 3, 4, 5 }, SubsetOf(ints1to5));644       Expect(new int[] { 2, 4, 6 }, Not.SubsetOf(ints1to5));645     }646     #endregion647 648     #region Property Tests649     [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 syntax657 658       // Constraint Syntax659       Assert.That(list, Has.Property("Count"));660       Assert.That(list, Has.No.Property("Length"));661 662       Assert.That("Hello", Has.Length.EqualTo(5));663       Assert.That("Hello", Has.Length.LessThan(10));664       Assert.That("Hello", Has.Property("Length").EqualTo(5));665       Assert.That("Hello", Has.Property("Length").GreaterThan(3));666 667       Assert.That(array, Has.Property("Length").EqualTo(4));668       Assert.That(array, Has.Length.EqualTo(4));669       Assert.That(array, Has.Property("Length").LessThan(10));670 671       Assert.That(array, Has.All.Property("Length").EqualTo(3));672       Assert.That(array, Has.All.Length.EqualTo(3));673       Assert.That(array, Is.All.Length.EqualTo(3));674       Assert.That(array, Has.All.Property("Length").EqualTo(3));675       Assert.That(array, Is.All.Property("Length").EqualTo(3));676 677       Assert.That(array2, Has.Some.Property("Length").EqualTo(2));678       Assert.That(array2, Has.Some.Length.EqualTo(2));679       Assert.That(array2, Has.Some.Property("Length").GreaterThan(2));680 681       Assert.That(array2, Is.Not.Property("Length").EqualTo(4));682       Assert.That(array2, Is.Not.Length.EqualTo(4));683       Assert.That(array2, Has.No.Property("Length").GreaterThan(3));684 685       Assert.That(List.Map(array2).Property("Length"), Is.EqualTo(new int[] { 1, 2, 3 }));686       Assert.That(List.Map(array2).Property("Length"), Is.EquivalentTo(new int[] { 3, 2, 1 }));687       Assert.That(List.Map(array2).Property("Length"), Is.SubsetOf(new int[] { 1, 2, 3, 4, 5 }));688       Assert.That(List.Map(array2).Property("Length"), Is.Unique);689 690       Assert.That(list, Has.Count.EqualTo(4));691 692       // Inherited syntax693       Expect(list, Property("Count"));694       Expect(list, Not.Property("Nada"));695 696       Expect("Hello", Length.EqualTo(5));697       Expect("Hello", Property("Length").EqualTo(5));698       Expect("Hello", Property("Length").GreaterThan(0));699 700       Expect(array, Property("Length").EqualTo(4));701       Expect(array, Length.EqualTo(4));702       Expect(array, Property("Length").LessThan(10));703 704       Expect(array, All.Length.EqualTo(3));705       Expect(array, All.Property("Length").EqualTo(3));706 707       Expect(array2, Some.Property("Length").EqualTo(2));708       Expect(array2, Some.Length.EqualTo(2));709       Expect(array2, Some.Property("Length").GreaterThan(2));710 711       Expect(array2, None.Property("Length").EqualTo(4));712       Expect(array2, None.Length.EqualTo(4));713       Expect(array2, None.Property("Length").GreaterThan(3));714 715       Expect(Map(array2).Property("Length"), EqualTo(new int[] { 1, 2, 3 }));716       Expect(Map(array2).Property("Length"), EquivalentTo(new int[] { 3, 2, 1 }));717       Expect(Map(array2).Property("Length"), SubsetOf(new int[] { 1, 2, 3, 4, 5 }));718       Expect(Map(array2).Property("Length"), Unique);719 720       Expect(list, Count.EqualTo(4));721 722     }723     #endregion724 725     #region Not Tests726     [Test]727     public void NotTests()728     {729       // Not available using the classic syntax730 731       // Constraint Syntax732       Assert.That(42, Is.Not.Null);733       Assert.That(42, Is.Not.True);734       Assert.That(42, Is.Not.False);735       Assert.That(2.5, Is.Not.NaN);736       Assert.That(2 + 2, Is.Not.EqualTo(3));737       Assert.That(2 + 2, Is.Not.Not.EqualTo(4));738       Assert.That(2 + 2, Is.Not.Not.Not.EqualTo(5));739 740       // Inherited syntax741       Expect(42, Not.Null);742       Expect(42, Not.True);743       Expect(42, Not.False);744       Expect(2.5, Not.NaN);745       Expect(2 + 2, Not.EqualTo(3));746       Expect(2 + 2, Not.Not.EqualTo(4));747       Expect(2 + 2, Not.Not.Not.EqualTo(5));748     }749     #endregion750 751     #region Operator Tests752     [Test]753     public void NotOperator()754     {755       // The ! operator is only available in the new syntax756       Assert.That(42, !Is.Null);757       // Inherited syntax758       Expect(42, !Null);759     }760 761     [Test]762     public void AndOperator()763     {764       // The & operator is only available in the new syntax765       Assert.That(7, Is.GreaterThan(5) & Is.LessThan(10));766       // Inherited syntax767       Expect(7, GreaterThan(5) & LessThan(10));768     }769 770     [Test]771     public void OrOperator()772     {773       // The | operator is only available in the new syntax774       Assert.That(3, Is.LessThan(5) | Is.GreaterThan(10));775       Expect(3, LessThan(5) | GreaterThan(10));776     }777 778     [Test]779     public void ComplexTests()780     {781       Assert.That(7, Is.Not.Null & Is.Not.LessThan(5) & Is.Not.GreaterThan(10));782       Expect(7, Not.Null & Not.LessThan(5) & Not.GreaterThan(10));783 784       Assert.That(7, !Is.Null & !Is.LessThan(5) & !Is.GreaterThan(10));785       Expect(7, !Null & !LessThan(5) & !GreaterThan(10));786 787       // No longer works at all under 3.0788       // TODO: Evaluate why we wanted to use null in this setting in the first place789 #if false790         // TODO: Remove #if when mono compiler can handle null791 #if MONO792         Constraint x = null;793         Assert.That(7, !x & !Is.LessThan(5) & !Is.GreaterThan(10));794         Expect(7, !x & !LessThan(5) & !GreaterThan(10));795 #else796         Assert.That(7, !(Constraint)null & !Is.LessThan(5) & !Is.GreaterThan(10));797         Expect(7, !(Constraint)null & !LessThan(5) & !GreaterThan(10));798 #endif799 #endif800     }801     #endregion802 803     #region Invalid Code Tests804     // This method contains assertions that should not compile805     // 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     #endregion820   }821 822 #endregion

Nunit 单元测试

 

单元测试参考资料

  • MSDN - Microsoft.VisualStudio.TestTools.UnitTesting
  • 单元测试之道
  • VS2012 Unit Test 个人学习汇总(含目录)
  • 单元测试的优点
  • 对比MS Test与NUnit Test框架