浅谈测试(1)---单元测试
在做项目当中发现很多开发人员没有单元测试的习惯,往往是写完代码后直接右键——commit,然后就完事大吉。这样做的严重后果就是在开发后期的集成测试中Bug百出,而且都是类似于变量忘记赋值、字符串拼接错误、界面忘记显示全部信息等等一系列非常小的Bug。这些Bug的存在直接导致集成测试的时候效率低下,工期延长……
试想仅仅因为一个string中的一个拼接错误,或者变量忘记赋值这些小错误,测试人员还要写个文档发送给开发人员,告诉他“错误显示可能是***个文件的***行的字符串拼接错了”或者“错误显示可能是***个文件中的用于显示模块有问题”,如果真的是这样那么不是测试人员先累死就是开发人员先郁闷死。效率太低了,太低了……
有些人可能说没有必要给开发人员说那么仔细啊,直接告诉他们哪个文件有问题,然后就让开发人员改去,改完调试完毕再提交(太狠了~)!如果真的这么做那么会涉及到下面几个问题。
1. 整个工程的所有代码是否可以让所有的开发人员看到?
商业化的工程是应该保密的,也就是说你只能看到自己的模块,其他的模块你看到的应该只是DLL。但是很多的开发团队没有这个意识,整个源码所有人可见,甚至于可读可写(更加悲了个催的~)!这样的话只能把安全寄托于程序员的自身素质喽,希望团队中不会有“害群之马”。
2. 开发人员有必要关注其他模块功能的具体实现么?
如果每个开发人员在调试的时候都需要了解其他开发者的实现过程的话,就相当于要求每个开发人员写完自己的代码还要看懂和自己模块相关的所有代码,这样的话效率也就不复存在了。试想在一堆不是自己写的代码中无限F11是个多么郁闷的事情!
3. 在调试的过程中其他模块是否已经完成?
如果其他模块没有完成难道还要等待他们完成后才能测试自己代码的正确性?而且调用的其他模块也必须是没有错误才行,否则更加乱套,你的代码中有Bug我的也有Bug,出了错不知道谁的问题,多么雷人的事!
效率太低,太低……
解决上面问题的最有效也是最直接的办法就是开发者自己动手进行单元测试。就像组装一个汽车一样,每个部门保证自己生产的小部件没有问题,然后再组装起来检测整个工程是否存在问题。
l 很多开发团队有以下几个误区
1. 开发与测试人员分开
2. 测试主要由测试人员负责,开发人员不应该做测试
没有错,开发人员和测试人员的确应该分工,分工可以让我们效率更高。但是这里的测试主要指的是集成测试,要是单元测试也要测试人员来做,很可能会导致上文中所提到的情况发生:一堆一堆的低级Bug涌现,琐碎、无价值的修改不断。
l 开发人员常常这样抱怨
“让他们(测试人员)测试去吧,有问题告诉我,我改了就得了!”
“写一个测试代码都快赶上原来的代码量了,麻烦死了!”
“有测试的时间三个模块都能写出来,太浪费时间了!”
……
l 前人的经验
其实在整个开发周期中,错误发现的越晚,单位错误修复成本越高。如图所示,错误的延迟解决必然导致整个项目成本的急剧增加。
下面简单介绍一下在Visual Studio中如何进行单元测试(以Visual Studio 2010为例)
1.所谓单元测试就是测试项目中的最小单元——方法。在需要测试的方法上面右键,选择“创建单元测试”。
2.在如下图的向导中选择要测试的类以及方法,你可以选择类中所有的方法进行测试,VS为每个方法创建一个对应的测试方法,所以说如果想测试整个类文件那么就应该把这个类中所有的方法勾选。(在这里只演示测试一个方法的过程)
3.Setting按钮是对测试方法的扩展设置,Output Project是选择测试代码的语言环境(C#或VB),以上两项默认即可。
4.点击OK后输入一个测试的名称,然后Create。
5.这样在资源管理器中添加了如图中箭头所指的几个文件,本示例中需要我们自己动手编写的是测试文件(DalUserInfoSqlTest.vb)。
6.打开DalUserInfoSqlTest.vb后在尾部能够看到如下代码,有三个需要TODO的地方。
1: '''
2: '''A test for AddInfo
3: '''
4: _
5: Public Sub AddInfoTest()
6: Dim target As IUserInfo = New DalUserInfoSql() ' TODO: Initialize to an appropriate value
7: Dim AddUser As EnUserInfo = Nothing ' TODO: Initialize to an appropriate value
8: Dim expected As Boolean = False ' TODO: Initialize to an appropriate value
9: Dim actual As Boolean
10: actual = target.AddInfo(AddUser)
11: Assert.AreEqual(expected, actual)
12: Assert.Inconclusive("Verify the correctness of this test method.")
13: End Sub
7.英文不是很难,简单的说就是需要我们提供一个初始输入、一个预期的输出。完成TODO后的代码如下
1: '''
2: '''A test for AddInfo
3: '''
4: _
5: Public Sub AddInfoTest()
6: Dim target As IUserInfo = New DalUserInfoSql() ' TODO: Initialize to an appropriate value
7: Dim AddUser As New EnUserInfo
8: AddUser.FillByOthers("UserID", "UserPwd", "管理员", "Register", "UserName", True)
9: Dim expected As Boolean = True
10: Dim actual As Boolean
11: actual = target.AddInfo(AddUser)
12: Assert.AreEqual(expected, actual)
13: 'Assert.Inconclusive("Verify the correctness of this test method.")
14: End Sub
8.在测试方法上右键“运行测试”(测试无需编译,直接运行即可)。
9.如果运行错误则测试结果中会显示失败。
10.双击错误条目则显示详细的错误信息,如下图。这时候需要开发人员查找自己代码是否存在错误并修改。
11.如果错误信息不足以帮助找到错误,那么还可以在测试窗口中右键进行调试(和一般的调试没有区别)。
12.将错误修改完成后,参照步骤8继续测试,如果排除了错误则显示通过,如下图。
13.本例中是测试DAL层的一个增加方法,查看数据库果然成功!