5

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

我注意到代码覆盖率指标和测试质量存在一个问题:100% 的代码覆盖率并不意味着代码真的经过测试。

有时测试会提供 100% 的覆盖率,即使它不能覆盖所有内容。问题在于覆盖定义,我们假设覆盖==可达代码

但事实并非如此,代码可能 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);
  }
}
4

2 回答 2

4

看看Jester,它执行突变测试。从网站:

Jester 查找测试未涵盖的代码。Jester 对您的代码进行一些更改,运行您的测试,如果测试通过,Jester 会显示一条消息,说明它所做的更改。Jester 包含一个用于生成网页的脚本,该网页显示所做的更改不会导致测试失败。

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

于 2012-04-12T18:59:20.653 回答
2

100% 的覆盖率绝不意味着 100% 的测试,任何声称这样做的人要么不理解,要么在对你撒谎。覆盖率测量只是测量在测试期间执行了哪些产品代码。有几十种方法可以编写产生 100% 覆盖率的测试,然后不完全测试您的代码。

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

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

于 2012-04-13T16:25:26.933 回答