junit:forkMode=“once”对测试正确性的影响

我想减少我们的构建(使用ant)运行测试所需的时间。目前我正在使用默认的forkMode,它在每个测试类()上分叉一个新的vmperTest

我正在考虑切换到,但我不确定这是否会以某种方式耦合测试,并可能在运行测试后给我假阳性和/或假阴性结果。forkMode="once"

问题:

  1. 每个测试用例是否会获得一个新的 ClassLoader,以便不再访问/查看以前运行中的所有静态引用?

  2. 是否还有其他事情会导致测试方法的测试依赖性/耦合性,这可能会改变行为(除了我不使用的本机库加载)

  3. 垃圾回收/最终确定,它们在每次测试后运行吗?(我不依赖它们,但我只是想得到一个完整的画面)


更新

根据目前的答案,在使用 forkMode 时,junit 似乎总是在每个 vm/fork 的所有测试用例之间共享一个类加载器。(所以 forkMode=“once” 确实意味着所有测试都有一个类加载器)

这有许多优点(更快的测试,并且可能导致测试因静态耦合而失败),但也有一些缺点(静态耦合仅在使用共享类装入器时才有效 - >误报)


答案 1
  1. 测试运行程序将有效地制作所有测试的单个套件并运行它们 - 因此只涉及一个类加载器。
  2. 是的,这意味着静态数据将在测试之间共享,这可能偶尔很方便,但会迫使您减少子句之间的静态耦合,这是一件好事。
  3. 通常没有任何显式GC,但您可以自己做。

通常,在一个 VM 中运行所有测试是一件好事。它迫使您查看静态耦合,并且速度要快得多。至关重要的是,这也是您的 IDE 运行它们的方式,这确实是运行测试的方式 - 尽可能接近编译的频率。


答案 2

请注意,默认模式为每个测试用例(即.class)分叉一个新的 VM,而不是为每个测试(即方法)分叉。在我当前正在测试的应用程序中,当我将 VM 重用于多个测试时会出现一些问题:对象和状态是早期测试遗留下来的,并阻止后续测试工作。如果您的应用程序结构良好,并且您的测试是严格独立的,这可能不是问题。我怀疑垃圾回收在每次测试后都会自动运行:众所周知,在任何情况下,确保在任何给定时间调用它都是非常困难的。


推荐