一般的白盒测试,用例设计的评估标准就是代码覆盖度。覆盖度不能光靠条件凑,Unit Test的代码也是有具体的分析方法的,不要有冗余。
常见的覆盖有六种:语句覆盖,判定覆盖,条件覆盖,判定/条件覆盖,组合覆盖和路径覆盖
1. 语句覆盖 Statement Coverage
“最弱覆盖”保证每个语句至少被执行一次,不考虑条件和分支
func foo(a , b int) int{
return a / b
}
那么我们只需要一个TestCase:a=2, b=1
就能满足代码覆盖率到100%,但是有明显问题,当b=0时,会有panic: runtime error: integer divide by zero
2. 判定(分支)覆盖 Decision Coverage
判定覆盖的测试用例要保证每一个分支都被执行至少一次,所以我们需要以下3个TestCase
TestCase1: a=1,b=1
TestCase2: a=-1,b=-1
TestCase3: a=2,b=-1
这样三个testcase就覆盖了I分支,II分支,III分支。进行判断分支覆盖的情况,实际上就是对于最终结果进行判断,因此我们可以根据最终结果的数量来判断TestCase数量(I、II、III分支)
3.条件覆盖 Condition Coverage
条件覆盖要求设计的测试用例能覆盖每个判定的真假值情况。即每个条件有一个真值,一个假值
以上一个流程图为例,一共有4个条件判断
a>0, a<0, b>0, b<0
在甲条件处,我们需要考虑a>0, a≤0, b>0, b≤0
在乙条件处,我们需要考虑a<0, a≥0, b≥0, b<0
因此需要4个TestCase:
TestCase1: a=1,b=1 甲条件的a>0 true和b>0 true, 乙条件的a<0 false和b<0 false
TestCase2: a=-1,b=-1 甲条件的a>0 false和b>0 false, 乙条件的a<0 true和b<0 true
TestCase3: a=-1,b=1 甲条件的a>0 false和b>0 true, 乙条件的a<0 true和b<0 false
TestCase4: a=1,b=-1 甲条件的a>0 true和b>0 false, 乙条件的a<0 false和b<0 true
总的来说条件覆盖比判定覆盖更强,使得判定中的每个条件都取到了不同的结果。缺陷在于只考虑判定条件,没有考虑判定结果。因此条件覆盖不保证判定覆盖
4.判定/条件覆盖 Decision/Condition Coverage
判定条件覆盖就是条件覆盖 + 判定覆盖,弥补了两者的缺点,包含了判定条件和判定结果两部分。
但是没有考虑到条件组合的情况,如果用笛卡尔乘积的方法进行组合,容易造成冗余
5. 组合覆盖 Branch Condition Combination Coverage
简单来说 组合覆盖= 条件覆盖 + 判定覆盖 + 判定/条件覆盖
就是设计出来的测试用例需要让每个判定中的各个条件的可能组合至少出现一次。
TestCase1: a=1, b=1
TestCase1: a=-1, b=-1
TestCase1: a=-1, b=1
TestCase1: a=1, b=-1
相对来说,测试用例的数量比较多
6.路径覆盖 Path Coverage
覆盖度最高,包含每条路径。优缺点明显,优点:对于所有可能路径进行覆盖。缺点:庞大且复杂的测试用例,用例数量呈指数级增长,实际工作中可操作性不强。
总结
一般来说我们做到组合覆盖就差不多了,测试用例多的问题很好解决。就是开发自己跑UT的时候多加点用例,发版本时候把UT删去就行了。
同时我希望读者能理解到一个点,为什么推荐程序里面有if条件判断嵌套越少越好。