覆盖率 vs 可达代码

5

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

我注意到代码覆盖率度量和测试质量存在一个问题:100%的代码覆盖率并不意味着代码真正得到了测试。

有时,即使测试并没有覆盖所有内容,它也会给出100%的覆盖率。问题在于覆盖率的定义,我们假设 覆盖率==可达代码

但这并不是真的,代码可能是100%可达的,但测试可能并没有完全覆盖代码。

以一个例子为例,这个测试(EMMA)给出了100%的覆盖率,但实际上它并没有覆盖将传递给服务模拟程序的值。因此,如果值发生更改,测试将不会失败。

例子:

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个回答

4
看看 Jester,它可以执行变异测试。从网站上了解到:
Jester 可以找到那些未被测试覆盖的代码,并对你的代码进行一些修改,然后运行你的测试文件。如果测试通过,Jester 就会显示一个消息来说明自己所做的更改。Jester 包括一个用于生成网页的脚本,显示不会造成测试失败的更改。
Jester 不同于代码覆盖率工具,因为它可以找到在测试过程中执行但实际上没有被测试的代码。Jester 的方法称为变异测试或自动错误种植。然而,Jester 并不是用来取代代码覆盖工具的,而只是作为一种补充方法。

很遗憾它不适用于当前版本的.NET。我本来很想试试看的。 - Gishu
我尝试过在谷歌上搜索有关变异框架的信息,但是没有一个与IDE(最好是IDEA)集成。 - Rrr
Jester在变异测试方面采取了相当天真的方法,因此速度非常缓慢。如果您正在考虑变异测试,您可能需要尝试更现代的系统,例如http://pitest.org或javalanche。 - henry

2

100%代码覆盖率从来不意味着100%的测试,任何声称如此的人要么不理解,要么在撒谎。代码覆盖率只是衡量测试期间执行了哪些产品代码的指标。有很多方法可以编写能够产生100%覆盖率的测试,但这些测试可能并不能充分地测试您的代码。

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

我曾经写过一篇关于这个话题的博客文章:Coverage Measurement中的缺陷,虽然它以Python为中心,但其概念都是相同的。


1
覆盖率告诉你一件事情:什么没有被测试。当查看覆盖率图表时,我不关心什么是绿色的,我关心的是什么是红色的。 - Ryan Nelson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接