所谓单元测试(unit testing),就是对软件中的最小单元进行检查和验证,其一般验证对象是一个函数或者一个类。值得一提的是,虽然单元测试是开发者为了验证一段代码功能正确性而写的一段代码,但是我们写一个单元测试的出发点并不是针对一段代码或者一个方法,而是针对一个应用场景(scenario),即在某些条件下某个特定的函数的行为。
0. 单元测试的必要性
单元测试不但会使你的工作完成得更轻松,而且会令你的设计变得更好,甚至大大减少你花在调试上面的时间。
(1)单元测试能让你确定自己的代码功能和逻辑的正确性,还可以让你增加对程序的信心,并且能够及早发现程序中的不足。
(2)在写好功能模块之前、之中和之后考虑好单元测试怎么写,不仅可以让你更加清楚你写的功能模块的逻辑,还能及早地改进一些不当的设计。
(3)每完成一块功能模块就用单元测试进行验证修改bug,比整个软件写完再验证调试要容易得多。而且有了单元测试,在整体软件出问题的时候,我们可以直接对怀疑的某模块在单元测试中进行debug,这往往比调试整个系统要容易得多。
(4)帮助我们及早地发现问题。有的时候对A的修改可能会影响看起来毫不相关的B,如果没有单元测试,A的修改checkin之后可能就会引发比较严重的问题。而如果在checkin之前能够运行所有的单元测试的话,B的单元测试可能就会发现引入的问题,从而阻止此次不当修改的checkin。
我想,其实很多程序员都应该知道单元测试重要性的那些大道理,只是要改变它就像要戒掉拖延症一样。明明知道那样不好并发誓下一次改进,却一直没有摆脱掉那些恶习。拜托,不要从明天或者从下一次开始了,就从现在开始吧!当你真正开始去写单元测试并坚持写,你会从中得到好处的,那时候你才会真正领悟到它的必要性。
1. 开始写你的第一个单元测试吧
我们先来用VS2012中自带的测试模块来写一个简单的单元测试吧。
新建一个solution,并添加工程MyMathLib,在该工程中添加MyMathLib类,并书写一个静态的Largest()函数来找出一个整型列表中的最大值。然后添加一个TestLargest工程,如图1所示,Add -> New Project 之后选择Test -> Unit Test Project。新建好test工程之后,你会得到一个test模板,即一个带有[TestClass] attribute标记的类和一个带有[TestMethod] attribute标记的空方法public void TestMethod1()。
Figure 1. Add unit test project
现在我们的solution就具有了图2中所示的目录结构,打开刚添加的TestLargest工程下的references,我们可以看到它自动引用了Microsoft.VisualStudio.QuanlityTools.UnitTestFramework。
Figure 2. Projects in the solution
分别在MyMathLib和TestLargest添加代码如下:
// MyMathLib.cs
namespace FirstUnitTest.MyMathLib
{
public static class MyMathLib
{
public static int Largest(List list)
{
int maxNum = Int32.MaxValue;
foreach (var num in list)
{
if (num > maxNum) maxNum = num;
}
return maxNum;
}
static void Main(string[] args)
{
}
}
}
// UnitTest1.cs
using FirstUnitTest.MyMathLib;
namespace FirstUnitTest.Test
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var list = new List() { 9, 8, 7 };
Assert.AreEqual(9, MyMathLib.MyMathLib.Largest(list));
}
}
}
写好之后你会发现有编译错误,cannot resolve MyMathLib.MyMathLib.Largest,所以我们在TestLargest工程里光添加using FirstUnitTest.MyMathLib;是不够的,还需要在references中增加对MyMathLib工程的引用。这样在TestMethod1()上单击右键选择Run Tests就可以在Test Explorer里看到单元测试的运行结果(如图3所示)。
原文转自:http://www.jianshu.com/p/7984955720e2