TDD中的单元测试写多少才够?
作者:网络转载 发布时间:[ 2014/4/18 13:52:10 ] 推荐标签:TDD 单元测试 驱动开发
测试驱动开发(TDD)已经是耳熟能详的名词,既然是测试驱动,那么测试用例代码要写在开发代码的前面。但是如何写测试用例?写多少测试用例才够?我想大家在实际的操作过程都会产生这样的疑问。
3月15日,我参加了thoughtworks组织的“结对编程和TDD Openworkshop”活动,聆听了tw的咨询专家仝(tong2)键的精彩讲解,并在讲师的带领下实际参与了一次TDD和结对编程的过程。活动中,仝键老师对到底写多少测试用例才够的问题,给出了下面一个解释:
我们写单元测试,有一个重要的原因是用来防止自己犯低级错误的。我们不能把写实现代码的人当作我们的敌人,一定要把全部情况都测到,以防止他们在里面故意留下各种隐蔽的陷阱。测试写的再多可能也没有办法覆盖全部情况,所以只要能让自己感到安全即可。怎样才能让自己感到安全呢?这是没有标准答案的,只能是写多了测试以后慢慢体会。
另外,写测试也要花时间的,比如compare这个方法的实现部分,我们只花了一两分钟写完了,而这些测试代码,我们花了足足半个多小时,这样做值得吗?对于简单的业务逻辑来说,当然是不值得的,毕竟我们还很多工作等着做,老板花钱是为了我们的产品代码,而不是测试代码。
再考虑一种情况,我要创业,想了一个点子,做了一个网站,我当然是想以快的速度把它做成型让别人用。如果我在完全不知道人们会不会喜欢的时候,先花大量时间写测试,后发现没人用只能丢掉,这些测试岂不是白写了。
所以还是上面那句话:单元测试是让你提升自己对代码的信心的,只要你感觉安全可以继续开发时够了,不是越多越好。
我相信上面一段解释对于本文中提出的问题大家都没有什么异议。但是这里我们不考虑特殊情况,在实际操作中,是否有办法对单元测试这一工作进行衡量?来判断是否足够?
使用代码覆盖率来衡量单元测试是否足够
常见的代码覆盖率有下面几种:
语句覆盖(Statement Coverage):这是常用也是常见的一种覆盖方式,是度量被测代码中每个可执行语句是否被执行到了。
判定覆盖(Desicion Coverage):它度量程序中每一个判定的分支是否都被测试到了。
条件覆盖(Condition Coverage):它度量判定中的每个子表达式结果true和false是否被测试到了。
路径覆盖(Path Coverage):它度量了是否函数的每一个分支都被执行了。
前三种覆盖率大家可以查看下面的引用的第3篇文章,这里不再多说。我们通过一个例子,来看看路径覆盖。比如下面的测试代码中有两个判定分支
int foo(int a, int b)
{
int nReturn = 0;
if (a < 10)
{// 分支一
nReturn+= 1;
}
if (b < 10)
{// 分支二
nReturn+= 10;
}
return nReturn;
}
我们仔细看看逻辑,nReturn的结果一共有4种可能,我们通过路径覆盖的方法设计出来的测试用例:
Perfect。但是实际中的代码往往比上面的例子复杂,如果代码中有5个if-else,那么按照路径覆盖的方法,至少需要25=32个测试用例。这样简直要疯掉了。
没必要追求代码覆盖率,真正要覆盖的是逻辑
简单追求代码结构上的覆盖率,容易导致产生大量无意义的测试用例或者无法覆盖关键业务逻辑。我们再看看上面解释的第一段话。
我们写单元测试,有一个重要的原因是用来防止自己犯低级错误的。我们不能把写实现代码的人当作我们的敌人,一定要把全部情况都测到,以防止他们在里面故意留下各种隐蔽的陷阱。测试写的再多可能也没有办法覆盖全部情况,所以只要能让自己感到安全即可。怎样才能让自己感到安全呢?这是没有标准答案的,只能是写多了测试以后慢慢体会。
相关推荐
更新发布
功能测试和接口测试的区别
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