让单元测试更完善的6个简单技巧
作者:网络转载 发布时间:[ 2012/11/13 13:57:37 ] 推荐标签:
单元测试的好处被整个开发产业认可。单元测试帮助我们确定代码如期工作,避免回归缺陷,甚至可以用来作为一种设计方法(测试驱动开发)。单元测试的问题开始于当之前写好的测试运行甚至编译失败。
有各种各样的原因导致单元测试失败-即一个软件缺陷的引入或一个特点的改变。也有一些错误原因导致特定的测试失败-大部分可以按照下面的一些简单的指引来避免。
在一个完美的世界里,一个测试只会终止在被测试的代码停止工作。在现实中,编写糟糕的测试失败仅仅是因为代码更改。
由于过渡修改或重写这些脆弱的测试增加,它们的效率降低。所以开发人员不关注这些测试并不在修复它们。几个星期过后有人删除测试只因为它们没有编译。
怎样编写健壮的单元测试
简单的事实是写出好的单元测试跟写出好的代码完全不一样。有些原则是一样然而有些完全不同。写出不会根据代码变化而停止的好的单元测试并不难并且可以通过下面几条简单的习惯很容易达到。
1、单元测试应该是不可分割的
一个单元测试应该不依赖于环境设置、其他测试、执行的顺序或者运行时特定的顺序。
运行相同的单元测试1000次应该返回相同的结果。
使用如静态变量,外部数据(如注册表,数据库)或环节设置这些全局状态可能会导致测试间的“漏洞”。测试运行的顺序不应该影响测试结果,因此需确保适当的初始化和清除测试间运行的全局状态或完全避免使用全局状态。
2、单元测试应该是确定的
按照之前的规定,一个测试无论它需要运行多少次都应该返回相同结果。使用多线程相关的对象(如计时器,线程)作为测试的一部分应该避免和尽量控制,用来确保测试不会因为不同时序而失败。
例如睡眠等时间相关的操作需要避免,因为这是困难的或者根本不可能保障测试不会失败。由于运行机器高的CPU使用率
有些开发人员编写单元测试用随机的数字/日期-引入的测试和去人什么时候失败的不确定性,由于测试数据每次运行都会变化,这样是不可能重复执行的
3、认识你正在测试的
测试一个特定场景/对象各个方面都没有问题。问题在于开发人员趋向于利用一种方法收集几个这样的测试,写出一些非常复杂而且脆弱的“单元测试”。
我找到的一个窍门是用测试场景和预期结果作为测试方法名的一部分。当一个开放人员在命名他的测试时遇到问题,说明他不确定测试是用来干嘛的。只测试一样东西的一个更易读的测试有额外的好处, 当简单的测试失败了它比一个又长又复杂的测试容易找到失败原因并且修复它。
4、注意测试范围
测试的范围和它的健壮性有直接关系。大部分测试有一个对象正在测试时响应或调用其他对象作为测试的一部分。这些外部依赖的对象的内部工作对测试来说并不重要,它们可以伪造。
使用孤立可以解决,因为测试不用初始化,不用设置测试用到的但不是真正要测试的对象,所以当这些外部对象变化了不会影响到测试结果。
5、测试什么(结果)而不是怎样测试
由于单元测试通常由相同的开发人员编写的,并且知道如何写代码实现的解决方案,如果不测试这个功能是怎样实现的是很难。
问题在于 执行趋向于变化,即使后结果是一样的测试也会失败。
另外一个因素当测试内部/私有方法或对象时引起的。有一个原因是这些方法试私有的-他们在类之外是不被看到的但又是该类内部机制的一部分。只测试私有方法如果你有很好的原因去实现,因为细微的重构可以导致测试中复杂的出错和失败
6、避免超出规格说明书
通过设置测试中每个独立的对象和测试的每个方面来创建一个良好定义的、可控的和严格的测试,测试中遵从精确过程流,是非常诱人的。问题在于测试中执行如此“约束”的场景阻止了不影响终结果的测试修改。
例如,不要创建一个测试期待一个特定的方法被准确的调用三次或只有连个定义的方法被调用(没有其它的)。有各种原因写出非常精确的测试,但是这种测试如此细微的处理执行起来只会变成一个非常脆弱的测试。用一个孤立的框架来设置外部对象默认的行为并且保证非预期的方法被调用(严格)时不会抛出异常
总结
编写强壮的单元测试并不难。只需要一些练习。上面列出的远远不够但列出了一些会帮助你写好单元测试的关键点。并记住一点如果一个精确的测试一致失败-找出根本原因并找跟好的方法测试该特性。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11