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         #endregion
115 
116         #region AreEqual
117         [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         #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单元测试

相关文章: