覆盖率与可达代码

时间:2012-04-12 18:49:02

标签: java unit-testing junit mocking code-coverage

问:如何检测真实的测试覆盖率?

我注意到代码覆盖率指标和测试质量存在一个问题: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);
  }
}

2 个答案:

答案 0 :(得分:4)

查看执行Jestermutation testing。来自网站:

  

Jester找到测试未涵盖的代码。杰斯特做了一些   更改代码,运行测试,以及测试是否通过Jester   显示一条消息,说明它的变化。 Jester包含一个脚本   用于生成显示未导致的更改的网页   测试失败。

     

Jester与代码覆盖率工具不同,因为它可以找到代码   这是通过运行测试而不是实际测试来执行的。   Jester的方法称为变异测试或自动错误   播种。但是,Jester并不是代码的替代品   覆盖工具,仅作为一种补充方法。

答案 1 :(得分:2)

100%的覆盖范围从未意味着100%经过测试,任何声称拥有该功能的人都不会理解,或者对您撒谎。覆盖率测量仅测量在测试期间执行的产品代码。有许多方法可以编写产生100%覆盖率的测试,然后不会对代码进行全面测试。

最简单的方法是编写一个调用product函数的测试,然后永远不会对返回值进行任何断言!

这是我写的关于这个主题的博客文章:Flaws in Coverage Measurement,它以Python为中心,但概念都是一样的。