JUnit 报告显示测试功能,而不是覆盖率

JUnit report to show test functionality, not coverage

团队领导的一个问题是团队中的人(有时甚至包括我自己)经常创建没有任何测试功能的 JUnit 测试。

这很容易完成,因为开发人员使用他们的 JUnit 测试作为工具来启动他​​们正在编码的应用程序部分,然后有意或无意地签入它而不进行任何断言测试或模拟验证。

后来人们忘记了测试不完整,但它们通过并产生了很好的代码覆盖率。 运行 启动应用程序并通过它提供数据将创建来自 Cobertura 或 Jacoco 的高代码覆盖率统计数据,但除了它 运行 没有爆炸的能力之外没有任何测试 - 我什至看到它有效 -在测试中使用大的 try-catch 块。

有没有可以测试测试的报告工具,这样我就不需要经常检查测试代码了?

我暂时兴奋地发现 Jester 通过更改被测代码(例如 if 子句)并重新 运行 来测试测试是否会破坏测试。

然而,这不是您可以在 CI 服务器上设置为 运行 的东西 - 它需要在命令行上设置,不能 运行 不显示它的 GUI,仅将结果打印到 GUI 上,并且还需要很长时间才能 运行。

PIT 是标准的 Java 变异测试器。来自他们的网站:

Mutation testing is conceptually quite simple.

Faults (or mutations) are automatically seeded into your code, then your tests are run. If your tests fail then the mutation is killed, if your tests pass then the mutation lived.

...

Traditional test coverage (i.e line, statement, branch etc) measures only which code is executed by your tests. It does not check that your tests are actually able to detect faults in the executed code. It is therefore only able to identify code the is definitely not tested.

The most extreme example of the problem are tests with no assertions. Fortunately these are uncommon in most code bases. Much more common is code that is only partially tested by its suite. A suite that only partially tests code can still execute all its branches (examples).

As it is actually able to detect whether each statement is meaningfully tested, mutation testing is the gold standard against which all other types of coverage are measured.

The quality of your tests can be gauged from the percentage of mutations killed.

它有一个对应的 Maven plugin 以使其易于作为 CI 构建的一部分进行集成。我相信下一个版本也将包括与 Maven 站点报告的正确集成。

此外,creator/maintainer 在 Whosebug 上非常活跃,并且擅长回答标记的问题。

尽可能在实现功能或修复测试应该处理的错误之前编写每个测试。功能或错误修复的顺序变为:

  1. 编写测试。
  2. 运行吧。在这一点上,如果它是一个很好的测试,它将失败。如果是的话 不会失败、更改、替换或添加它。
  3. 当你有一个失败的测试时,实现它应该的功能 去测试。现在它应该通过了。

听起来您需要考虑像 Jacoco, the gradle plugin provides report on coverage. I also use the EclEmma Eclipse 插件这样的覆盖工具来获得相同的结果,但在 IDE.

中有相当好的集成

根据我的经验,即使没有空操作单元测试,Jacoco 也提供了可接受的数字。因为它似乎能够准确地确定测试的代码路径。无操作测试的覆盖率分数较低或为 0%,并且随着测试变得更加完整,分数会增加。

更新 解决反对者的问题。也许更适合解决这个问题的工具是 PMD。可以在 IDE 或构建系统中使用。通过适当的配置和规则开发,它可以用来找到这些不完整的单元测试。我过去曾用它来查找过去缺少某些安全相关注释的方法。

您有多种选择:

  • 您可能可以使用一些代码分析工具(例如 checkstyle)来验证每个测试是否都有断言。或者使用 JUnit 规则来验证这一点,但两者都很容易被欺骗并且仅在表面层面起作用。

  • Jester 所做的突变测试又是一种可行的技术解决方案,@Tom_G 似乎有一个可能可行的工具。但是这些工具(以我的经验)非常慢,因为通过 更改代码、运行 测试、分析结果 一遍又一遍地工作。因此,即使是很小的代码库也会花费很多时间,我什至不会考虑在实际项目中使用它。

  • 代码审查:这种糟糕的测试很容易被代码审查发现,无论如何,它们应该成为每个开发过程的一部分。

所有这一切还只是表面上的划痕。您应该思考的一个大问题是:为什么开发人员很想创建代码只是为了启动应用程序的某个部分?他们为什么不为他们想要实现的东西编写测试,所以几乎不需要启动应用程序的部分。接受一些自动化单元测试的培训,尤其是 TDD/BDD,即首先编写测试的过程。

根据我的经验,您很可能会听到这样的话:我们无法测试这个,因为....您需要找到开发人员的真正原因,不能或不想编写这些测试,这可能是也可能不是他们陈述的原因。然后解决这些原因,那些令人厌恶的测试就会自行消失。

你要找的确实是变异测试。

关于工具支持,你可能还想看看Major 变异框架(mutation-testing.org),它非常高效且可配置。主要的 使用编译器集成的修改器,让您可以很好地控制 应该改变和测试什么。据我所知少校还没有 生成图形报告而不是数据 (csv) 文件,您可以 以您想要的任何方式处理或可视化。