条件覆盖和单元测试
Condition Coverage and Unit Testing
在编写单元测试(使用junit)时,是否需要将测试方法分开以达到完整的条件覆盖?
以这个片段为例:
int foo(boolean a, boolean b, boolean c){
if(a && b && c)
return 1;
else return 0;
}
是否为条件覆盖写一个方法和不同的断言更好?还是每种情况一种方法?
@Test
void conditionsTest(){
assertEqual(0, foo(true, false, false));
assertEqual(0, foo(true, true, false));
assertEqual(1, foo(true, true, true));
...
}
或
@Test
void condition1Test(){
assertEqual(0, foo(true, false, false));
}
@Test
void condition2Test(){
assertEqual(0, foo(true, true, false));
}
@Test
void condition3Test(){
assertEqual(1, foo(true, true, true));
}
虽然不需要拆分测试,但这样做更好:
一体化测试功能将在第一个失败断言时中止执行。没有关于其他组合的信息。分开后,您将获得有关哪些组合完全失败的更多详细信息。请注意,parameterized tests 将实现相同的效果。
从覆盖率的角度来看,一体化测试将在单个测试中积累覆盖率。无法分析每个条件组合的贡献。这在寻求更复杂的条件覆盖率指标(如 MC/DC.
时变得更有价值
当然:第二个方面取决于覆盖工具提供的数据收集粒度。我们公司的工具 Coco 收集每个测试函数的覆盖率,但目前仅针对 C、C++ 和 C# 收集覆盖率。您可能想要寻找 Java 代码的等效功能。
在编写单元测试(使用junit)时,是否需要将测试方法分开以达到完整的条件覆盖?
以这个片段为例:
int foo(boolean a, boolean b, boolean c){
if(a && b && c)
return 1;
else return 0;
}
是否为条件覆盖写一个方法和不同的断言更好?还是每种情况一种方法?
@Test
void conditionsTest(){
assertEqual(0, foo(true, false, false));
assertEqual(0, foo(true, true, false));
assertEqual(1, foo(true, true, true));
...
}
或
@Test
void condition1Test(){
assertEqual(0, foo(true, false, false));
}
@Test
void condition2Test(){
assertEqual(0, foo(true, true, false));
}
@Test
void condition3Test(){
assertEqual(1, foo(true, true, true));
}
虽然不需要拆分测试,但这样做更好:
一体化测试功能将在第一个失败断言时中止执行。没有关于其他组合的信息。分开后,您将获得有关哪些组合完全失败的更多详细信息。请注意,parameterized tests 将实现相同的效果。
从覆盖率的角度来看,一体化测试将在单个测试中积累覆盖率。无法分析每个条件组合的贡献。这在寻求更复杂的条件覆盖率指标(如 MC/DC.
时变得更有价值
当然:第二个方面取决于覆盖工具提供的数据收集粒度。我们公司的工具 Coco 收集每个测试函数的覆盖率,但目前仅针对 C、C++ 和 C# 收集覆盖率。您可能想要寻找 Java 代码的等效功能。