收集并在其自己的JVM中与每个测试类并行运行所有junit测试(按类而不是按方法进行并行化)

Cre*_*eos 2 junit unit-testing intellij-idea gradle android-studio

问题
我有一堆junit测试(许多带有自定义的运行器,例如PowerMockRunner或JUnitParamsRunner)都在某个根包下tests(它们tests位于各个深度的子包中)。

我想收集所有测试包,tests并在不同的JVM中并行运行每个测试类。理想情况下,并行化是可配置的,但是number_of_cores的默认设置也完全可以。请注意,我不想在自己的JVM中运行每个方法,而是在每个类中运行。

背景
我通过注释@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(JUnitParamsRunner.class)许多测试将PowerMock与JUnitParams结合使用。我有大约9000个单元测试,可以在“确定的”时间内完成,但是我有8核CPU,并且默认的一次一次测试运行程序未充分利用这些系统。因为我经常运行测试,所以增加了额外的时间,我真的想并行运行测试类。

请注意,不幸的是,在大量测试中,我需要模拟静态方法,这是使用PowerMock的部分原因。

我尝试过的事情
由于必须模拟静态方法,因此无法使用类似的方法com.googlecode.junittoolbox.ParallelSuite(这是我最初的解决方案),因为它在相同的JVM中运行所有内容,并且静态模拟被交错并弄乱了。至少在我看来,基于我得到的错误。

我一点都不了解JUnit堆栈,但是经过一番摸索,看来另一种选择可能是尝试编写并注入自己的JUnit,但是RunnerBuilder我不确定是否可以从一个内部生成另一个JVM进程。RunnerBuilder,不太可能。我认为正确的解决方案是将某种形式的束缚当作一项艰巨的任务来解决。

我还发现了一些Android Studio(Intellij)测试选项,但是唯一可用的fork选项method不是我想要的。我目前正在探索此解决方案,因此也许我会解决,但我想我会并行地询问社区,因为我还没有太多锁定。

更新:终于能够使Android Studio(Intellij)使用选项Test Kind :(All in directory出于某些原因,包选项未进行递归搜索)和选择fork模式来收集我的所有测试Class。但是,它仍然运行顺序找到的每个测试类,并且我看不到有关并行化的选项。这是如此接近我想要的,但不是很... :(

Cre*_*eos 5

暂定答案

不要让这个答案阻止您发布更好的答案。但是,如果一周之内我看不到更好的解决方案,则将其标记为正式解决方案。

我注意到,Android Studio没有使用Intellij(Android Studio)内置的JUnit运行配置,而是有很多预构建gradle任务,其中一些任务涉及测试。但是,它们表现出相同的顺序执行问题。然后,我发现使用gradle运行并行测试任务,并将以下语句添加到我的根build.gradle文件中:

subprojects {
    tasks.withType(Test) {
        maxParallelForks = Runtime.runtime.availableProcessors()
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好用,我的CPU现在固定为100%(在大多数运行中,由于未完成的测试类的数量变得<可用处理器,显然利用率下降了)。

该解决方案的缺点是它不与Android Studio的(Intellij)漂亮的junit运行器UI集成。因此,在gradle任务正在进行的过程中,我无法真正看到测试完成的速度,等等。在任务执行结束时,它只会吐出整个运行时以及指向HTML生成的报告的链接。这只是次要点,我可以完全接受,但是如果我能弄清楚如何改善使用JUnit运行器UI的解决方案,那将是很好的。