我应该以 100% 的 Jacoco 测试覆盖率为目标吗?

Should I aim for 100% test coverage on Jacoco?

我目前正在努力提高一个项目的测试覆盖率,它大约是 93%,我正在朝着 100% 的方向努力。

我注意到未涵盖的块之一是 main 方法,它看起来像这样:

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

尽管该应用程序有 90 多个测试,并且其中一些带有 @SpringBootTest 注释,但此 main 方法 仍未涵盖。

我是否应该为此担心并确保获得 100% 的覆盖率?还是我太完美了,某些事情不值得测试,就像上面的例子?

为什么上面的代码没有通过测试运行?我是否需要显式调用 main 方法才能使其成为 运行?我期待它在应用程序启动时被调用。

您不会为了乐趣而进行单元测试。因此,您也会出于不同的目的查看覆盖范围。

目的是:构建具有所需质量的软件。你衡量事情和设定目标不是因为你可以,而是因为这样做的过程有助于提高产品质量。

因此:当您可以清楚地定义测试此类代码的附加值时,就值得在这里投入时间。特别是因为为此投入时间会消耗你无法用于其他事情的能量。

长话短说:与您团队中的人员坐下来评估 return 此类测试的投资(以及超出 100% 覆盖率等目标),然后关注结果。换句话说:不要(过多)寻求陌生人的建议来确定自己的优先事项。您了解您的产品,而我们不知道。

Should I aim to 100% test coverage[...]?

是的。

但是你应该覆盖代码行,而是需求

您的自动化测试(单元测试模块测试验收测试)应该涵盖100% 的需求在项目文档中确定。

实现这一目标的最佳方法是测试驱动开发

TDD 不会导致 100% 的覆盖率,但它创建了一个值得信赖的安全网,作为一定数量的可衡量测试覆盖率,它更有价值。

我应该以 100% 为目标吗?是的,总是!。然而,话虽如此,任何超过 90% 的东西都被认为是好的。不可能在所有情况下都达到 100%。

谈论 "main method",因为它只是用于启动 spring 引导应用程序并且不涵盖任何功能,您可以简单地排除包含主要内容的 class使用属性标记内的以下代码行从 pom.xml 文件中的覆盖方法:

 <sonar.coverage.exclusions>
  **/com/example/test/MainApplication.java
</sonar.coverage.exclusions>

代码覆盖率本身是一个无用的指标。它不会告诉您 code/requirements 是如何被覆盖的。它只能指向没有完全覆盖的地方。通过实际上不检查任何内容的可怕测试很容易达到 100%。

此外 - 如果人们接触到指标,他们会尽其所能来改进指标。而不是做有用的事。因此(至少在我的实践中)在引入这些指标后,人们开始编写覆盖率更差的更糟糕的测试(我在这里不是在谈论线路覆盖率)。

如果您真的关心测试质量,您应该进行代码审查。如果您喜欢指标并希望坚持 line/branch 覆盖范围,至少还要引入突变测试。

所以最后:不,你不应该试图达到 100% 的线路或分支覆盖率。

我同意我们应该以 100% 的覆盖率为目标。 valid argument main 方法不是生成的代码,您可能可以在该方法中编写一些额外的逻辑。所以你应该写一个覆盖它的测试。

对于 main 方法到 bootstrap 一个 Spring 引导应用程序的特定示例,我可以建议以下简明的 JUnit 5 测试

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.Test;

class ApplicationTest {

  @Test
  void main() {
    assertDoesNotThrow(() -> Application.main(new String[]{}));
  }

}