Java junit:forkMode的影响=";“一次”;关于测试正确性

Java junit:forkMode的影响=";“一次”;关于测试正确性,java,unit-testing,ant,junit,continuous-integration,Java,Unit Testing,Ant,Junit,Continuous Integration,我想减少构建(使用ant)运行测试所需的时间。 目前我使用的是默认值,在每个测试类上派生一个新的vm(perTest) 我正在考虑切换到forkMode=“once”,但我不确定这是否会以某种方式耦合测试,并且在运行测试后可能会给我假阳性和/或假阴性结果 问题: 每个测试用例是否都会得到一个新的类加载器,以便以前运行的所有静态引用不再可访问/可见 是否有其他因素导致测试方法的测试依赖性/耦合性,这些因素可能会改变行为(除了我不使用的本机库加载之外) 垃圾收集/终结如何,它们是否在每次测试后运行?

我想减少构建(使用ant)运行测试所需的时间。 目前我使用的是默认值,在每个测试类上派生一个新的vm
perTest

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

问题:

  • 每个测试用例是否都会得到一个新的类加载器,以便以前运行的所有静态引用不再可访问/可见

  • 是否有其他因素导致测试方法的测试依赖性/耦合性,这些因素可能会改变行为(除了我不使用的本机库加载之外)

  • 垃圾收集/终结如何,它们是否在每次测试后运行?(我不依赖它们,但我只想了解完整的情况)

  • 更新

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

    这有许多优点(更快的测试,可能会因为静态耦合而导致测试失败),但也有一些缺点(静态耦合,只有在使用共享类加载器时才会工作->假阳性)

    看看这个,我会大胆猜测:

  • forkMode=“once”只会得到一个类加载器
  • 您将无法再访问Ant环境
  • GC将在生成的GC中执行(如果forceMode=“once”),这意味着它不是在每次测试运行之后执行的

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

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

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

    1。从条目的哪一部分可以得出结论,所有测试只共享一个类加载器?2.ant环境超出了范围(perTest也是分叉的)。3.System.gc()可能会被隐式调用…您关于默认forkMode的陈述是不正确的,因为实际上页面上说“perTest”为每个TestCase类创建一个新的VM。”这符合我的经验。然而,它确实使用“test”来表示其他地方的“testcase”。JUnit开发人员的术语似乎并不总是一致的。啊,我明白了,谢谢你指出这一点,我将更新这个问题。我大部分同意你的说法,但是共享静态数据可能会导致误报结果,从而产生一切正常的错觉(由于在这种情况下不会发现的静态耦合)当然,这是真的-当测试在隔离运行时失败时,我经常会发现这些问题。我认为测试顺序是随机的。更新看起来像一个新问题,使现有答案看起来不合适。新问题可以在这里找到:您的更新有点误导。JUnit正在共享一个类负载使用`forkMode=“once”时,在所有测试用例之间使用r,但不能在其他forkmodes之间使用r,因为您不能在运行的vms之间共享类加载器。我已经更新了这个问题,希望现在更好。