聚仙亭

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  12 随笔 :: 2 文章 :: 22 评论 :: 0 引用
 

单元测试是保证代码质量最基本的手段,但是现在的开发中却对单元测试不够重视。有的人认为编译器就是我们的代码质量保证,还有的人认为正确的调试就是测试,还有的人认为使用这个软件就是测试,这样的认识都是存在问题的。下面讲讲怎么样的单元测试才是好的单元测试。

单元测试应该准确、快速地保证程序基本模块的正确性。下面是验证单元测试好坏的一系列标准:

一、           单元测试应该在最低的功能/参数上验证程序的正确性;

单元测试应该测试程序中最基本的单元——如C#中的类,在此基础上,可以测试一些系统中最基本的功能点(这些功能点由几个基本类组成),从面向对象的设计原理出发,系统中最基本的功能点也应该由一个类及其方法来表现。单元测试要测试API中的每一个方法及每一个参数。

二、           单元测试必须由最熟悉代码的人(程序的作者)来写;

代码的作者最了解代码的目的、特点和实现的局限性。所以没有比作者更合适的人选。

就算作者没有时间写测试代码,也应该对此单元测试进行负责。

三、           单元测试过后,机器状态保持不变;

如果单元测试创建了临时的文件或者目录,在数据库中创建或修改了记录,都要删除临时数据。保证单元测试可以重复快速进行;

四、           单元测试要快(一个测试运行时间是几秒钟,而不是几分钟);

快,才能保证效率。一个软件中有几十个基本模块(类),每个模块又有几个方法,基本上要求一个类的测试在几秒钟内完成。如果软件有相互独立的几个层次,那么在测试组中进行分类,分类进行测试。比如我只修改了“用户界面”的代码,我只需要运行“用户界面”的单元测试。

五、           单元测试应该产生可重复,一致的结果;

如果单元测试的结果是错的,那一定是程序出了问题,而且这个错误一定是可以重复的。一般情况下不要使用随机数以增加测试的真实性。

六、           独立性,单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据以保持单元测试的独立性;

程序中的各个模块都是相互依赖的,一般情况下,单元测试中的模块可以直接引用其它的模块,并期待其它的模块能返回正确的结果。如果其它模块很不稳定、未完成,或者运行比较费时,这是可以人为地构造数据以保证这个单元测试的独立性。

七、           单元测试应该覆盖所有的代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,单元测试必须测试公开的和私有的函数/方法;

如果你的模块中某个错误处理路径很难到达,那你要想想是否可以把这个错误处理拿掉。要注意一点:100%的代码覆盖率并不等同于100%的正确性。

八、           单元测试应该集成到自动测试的框架中;

一个重要的措施是要把测试自动化,这样每个人都能很容易地运行单元测试。团队一般在每日构建(在敏捷开发中要求每天都能够提供一个可以运行的版本进行构建)中运行单元测试,这样每个单元测试的错误就能及时发现并得到修改。

九、           单元测试必须和产品代码一起保存和维护。

单元测试必须和代码一起进行版本维护。如果不是这样,过一阵代码和单元测试就会出现不一致,而且所有代码的作者要花时间来确认那些是程序出现的错误,那些是由于单元测试更新滞后造成的错误。这样就失去了单元测试的意义,同时又给大家增加了负担。如此折腾多次以后,大家就会觉得维护单元测试是一件很费时费力的事。

以上就是提到的单元测试好的建议,当然并不全面。希望能够得到大家的讨论和学习。

最后申明一下,上面的所有内容全部出自于《移山之道—VSTS软件开发指南》一书,如果大家对更多的内容感兴趣,可以去看看。

posted on 2008-01-15 12:36 罗嗦——.net学习之路 阅读(2206) 评论(9) 编辑 收藏

评论

#1楼 2008-01-15 13:14 qmxle[未注册用户]
单元测试要快(一个测试运行时间是几秒钟,而不是几分钟);

一个1秒钟的单元测试,已经太费时了。
 回复 引用   

#2楼 2008-01-15 14:15 留恋星空      
HEHE
 回复 引用 查看   

#3楼 2008-01-15 15:22 Solog      
#1楼
请教用VS自带的单元测试已经够快了,如何做到更快速有效的单元测试
 回复 引用 查看   

#4楼 2008-01-15 17:54 Anders06      
>>单元测试必须由最熟悉代码的人(程序的作者)来写
貌似倡导先有测试Case后有代码吧。

 回复 引用 查看   

#5楼 2008-01-15 22:06 Vincent      
七、单元测试应该覆盖所有的代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,单元测试必须测试公开的和私有的函数/方法;

我个人很不赞同去测试私有的函数和方法这个观点,既然出现私有的限制,必然也会有一个相映的公有的方式的来调用它,那么这个时候私有方法和函数的UnitTest就应该在这个公有的方法上来实现.
 回复 引用 查看   

#6楼 2008-02-21 21:05 Shinn      
--引用--------------------------------------------------
Anders06: >>单元测试必须由最熟悉代码的人(程序的作者)来写
貌似倡导先有测试Case后有代码吧。


--------------------------------------------------------

你说的这个是测试驱动开发,这本书只要求由开发者来写单元测试,而且是在编码完成后再写
 回复 引用 查看   

#7楼 2008-07-23 14:25 stan0714[未注册用户]
不知道作者做过单元测试没有,就发表这篇文章!(请原谅我拍砖)

二、单元测试必须由最熟悉代码的人(程序的作者)来写;
通常自测自己代码通常都会忽略掉自己不会在意的问题。当然,自测是单元测试中的一种方式,但不是必须的~~~

七、单元测试应该覆盖所有的代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,单元测试必须测试公开的和私有的函数/方法;
单元测试中,对于私有函数/方法的测试是比较难的。(你可以看看别人去发表的一个测试私有方法的测试框架的文章)。况且单元测试应该覆盖所有的代码路径但是通常却做不到这一步,因为太难了。
 回复 引用   

#8楼 2008-07-23 14:26 stan0714[未注册用户]
--引用--------------------------------------------------
qmxle: 单元测试要快(一个测试运行时间是几秒钟,而不是几分钟);
<br>
<br>一个1秒钟的单元测试,已经太费时了。
--------------------------------------------------------
对于不同的单元测试模块,其性能指标是不同的,所以1秒、几秒都不是绝对的。
 回复 引用   

#9楼[楼主] 2008-07-23 15:06 罗嗦——.net学习之路      
--引用--------------------------------------------------
stan0714: 不知道作者做过单元测试没有,就发表这篇文章!(请原谅我拍砖)

二、单元测试必须由最熟悉代码的人(程序的作者)来写;
通常自测自己代码通常都会忽略掉自己不会在意的问题。当然,自测是单元测试中的一种方式,但不是必须的~~~

七、单元测试应该覆盖所有的代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,单元测试必须测试公开的和私有的函数/方法;
单元测试中,对于私有函数/方法的测试是比较难的。(你可以看看别人去发表的一个测试私有方法的测试框架的文章)。况且单元测试应该覆盖所有的代码路径但是通常却做不到这一步,因为太难了。
--------------------------------------------------------
首先,自测是最基本的一种方式,当然也不能排除其他人来写测试代码的可能,但是由他人完成的代价就是增加和此人沟通细节的时间;
至于最后一点我就不明白了,首先软件是有代价的,我不可能对所有的代码进行覆盖是因为时间、金钱等多方面的因素制约造成的,从《好的单元测试标准》这样的标题就可以看出是一种较为良好和优秀的标准,没有说强制要求去测试每一个函数,包括私有的,很显然这个是由于每时间做或者做起来难的问题,而不是这样的测试不需要不对的问题。(可能就是标准和实际操作方面的距离吧)
 回复 引用 查看