【问题标题】:Should I aim for 100% test coverage on Jacoco?我是否应该针对 Jacoco 实现 100% 的测试覆盖率?
【发布时间】:2017-11-17 18:47:45
【问题描述】:

我目前正在努力增加一个项目的测试覆盖率,大约是 93%,我正在努力实现 100%。

我注意到其中一个未被覆盖的块是 ma​​in 方法,它看起来像这样:

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

尽管应用程序有超过 90 个测试,并且有些带有 @SpringBootTest 注释,但这个 ma​​in 方法 仍然没有被覆盖。

我是否应该为此担心并确保获得 100% 的覆盖率?还是我过于完美主义者,并且某些东西根本不值得测试,就像上面的例子?

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

【问题讨论】:

  • 你会为这个方法测试什么? args 解析器在春季工作?它找到了 Application 类?
  • 在我看来,它更像是一个回归测试。如果有人向该方法添加了一些代码,使其行为不端。那有意义吗?如果没有,我是否应该不测试这种方法并告诉 jacoco 以某种方式忽略它?
  • 您不应该这样做,所付出的努力并不能涵盖由此带来的实际好处。通常,您会希望使用更高级别的测试来测试这样的地方,这些测试会将您的应用程序视为可执行文件而不是代码。此外,覆盖率本身并不能证明任何事情——只是代码是在测试期间执行的,它并不能说明它是否正确,它只是一个附带指标。
  • @Etki 测试永远无法证明perfection

标签: java spring spring-boot junit code-coverage


【解决方案1】:

您不会为了好玩而进行单元测试。因此,您还会出于不同的目的查看覆盖率。

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

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

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

【讨论】:

    【解决方案2】:

    我是否应该以 100% 的测试覆盖率为目标[...]?

    是的。

    但您应该涵盖代码行,而应涵盖要求

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

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

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

    【讨论】:

      【解决方案3】:

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

      谈论“主方法”,因为它仅用于启动 Spring Boot 应用程序并且不涵盖任何功能,您可以简单地将包含主方法的类排除在 pom.xml 文件的覆盖范围之外,使用属性标签内的以下代码行:

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

      【讨论】:

        【解决方案4】:

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

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

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

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

        【讨论】:

          【解决方案5】:

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

          对于引导 Spring Boot 应用程序的 main 方法的特定示例,我可以提出以下简洁的 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[]{}));
            }
          
          }
          

          【讨论】:

            猜你喜欢
            • 2019-10-28
            • 1970-01-01
            • 2013-07-05
            • 1970-01-01
            • 1970-01-01
            • 2016-04-07
            • 2016-11-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多