我注意到代码覆盖率指标和测试质量存在一个问题:100%的代码覆盖率并不意味着代码经过了真正的测试。
有时测试会提供100%的覆盖率,即使它没有涵盖所有内容。问题在于覆盖范围定义,我们假设 coverage ==可达代码。
但事实并非如此,代码可以100%可达,但不会100%覆盖测试。
看一下示例,此测试提供100%覆盖率(EMMA),但实际上它不包括将传递给服务模拟的值。因此,如果值将被更改,测试将不会失败。
示例:
public class User {
public static final int INT_VALUE = 1;
public static final boolean BOOLEAN_VALUE = false;
public static final String STRING_VALUE = "";
private Service service;
public void setService(Service service) {
this.service = service;
}
public String userMethod() {
return service.doSomething(INT_VALUE, BOOLEAN_VALUE, STRING_VALUE);
}
}
并测试它:
public class UserTest {
private User user;
private Service easyMockNiceMock;
@Before
public void setUp() throws Exception {
user = new User();
easyMockNiceMock = EasyMock.createNiceMock(Service.class);
}
@Test
public void nonCoverage() throws Exception {
// given
user.setService(easyMockNiceMock);
expect(easyMockNiceMock.doSomething(anyInt(), anyBoolean(), (String) anyObject())).andReturn("");
replay(easyMockNiceMock);
// when
user.userMethod();
// then
verify(easyMockNiceMock);
}
}
答案 0 :(得分:4)
查看执行Jester的mutation testing。来自网站:
Jester找到测试未涵盖的代码。杰斯特做了一些 更改代码,运行测试,以及测试是否通过Jester 显示一条消息,说明它的变化。 Jester包含一个脚本 用于生成显示未导致的更改的网页 测试失败。
Jester与代码覆盖率工具不同,因为它可以找到代码 这是通过运行测试而不是实际测试来执行的。 Jester的方法称为变异测试或自动错误 播种。但是,Jester并不是代码的替代品 覆盖工具,仅作为一种补充方法。
答案 1 :(得分:2)
100%的覆盖范围从未意味着100%经过测试,任何声称拥有该功能的人都不会理解,或者对您撒谎。覆盖率测量仅测量在测试期间执行的产品代码。有许多方法可以编写产生100%覆盖率的测试,然后不会对代码进行全面测试。
最简单的方法是编写一个调用product函数的测试,然后永远不会对返回值进行任何断言!
这是我写的关于这个主题的博客文章:Flaws in Coverage Measurement,它以Python为中心,但概念都是一样的。