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

Unit testing 收集所有junit测试并在其自己的JVM中与每个测试类并行运行(按类并行化,而不是按方法并行化),unit-testing,android-studio,intellij-idea,gradle,junit,Unit Testing,Android Studio,Intellij Idea,Gradle,Junit,问题 我有一堆junit测试(许多都带有自定义运行程序,如PowerMockRunner或JUnitParamsRunner),都在某个根包测试中(它们位于不同深度的测试的不同子包中) 我想收集包tests下的所有测试,并在不同的JVM中并行运行每个测试类。理想情况下,并行化是可配置的,但默认的\u核数也完全可以。注意,我不想在每个方法自己的JVM中运行每个方法,而是在每个类中运行 背景 对于我的许多测试,我通过注释@RunWith(PowerMockRunner.class)和@powermo

问题
我有一堆junit测试(许多都带有自定义运行程序,如PowerMockRunner或JUnitParamsRunner),都在某个根包
测试中(它们位于不同深度的
测试的不同子包中)

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

背景
对于我的许多测试,我通过注释
@RunWith(PowerMockRunner.class)
@powermockrunnerregate(JUnitParamsRunner.class)
将PowerMock与JUnitParams结合使用。我有大约9000个单元测试,这些测试在“正常”的时间内完成,但我有一个8核CPU,默认的单次测试运行程序严重未充分利用系统。由于我经常运行测试,额外的时间加起来,我真的希望并行运行测试类

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

我所尝试的
由于必须模拟静态方法,因此不可能使用像
com.googlecode.junittoolbox.ParallelSuite
(这是我的初始解决方案)这样的东西,因为它在同一个JVM中运行所有东西,而静态模拟会被交错和混乱。至少从我所犯的错误来看是这样的

我根本不知道JUnit堆栈,但在仔细研究之后,另一种选择似乎是尝试编写并注入我自己的
RunnerBuilder
——但我不确定是否可以从
RunnerBuilder
中生成另一个JVM进程,这是不可能的。我认为正确的解决办法应该是某种作为一项渐进任务存在的驾驭

我还发现了一些Android Studio(Intellij)测试选项,但唯一可用的fork选项是
方法
,这不是我想要的。我目前正在探索这个解决方案,所以也许我会找到它,但我想我会同时询问社区,因为我还没有太多的锁


更新:终于能够让Android Studio(Intellij)使用选项Test Kind:
目录中的所有测试
(出于某种原因,包选项没有进行递归搜索)和拾取叉模式
,收集我的所有测试。但是,这仍然会按顺序运行找到的每个测试类,并且我没有看到关于并行化的选项。这非常接近我想要的,但不完全…:(

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

subprojects {
    tasks.withType(Test) {
        maxParallelForks = Runtime.runtime.availableProcessors()
    }
}
这工作得很好,我的CPU现在固定在100%(在大部分运行中,由于未完成测试类的数量变得越来越少,处理器利用率明显下降)


此解决方案的缺点是它没有与Android Studio(Intellij)集成相当不错的junit runner UI。因此,当gradle任务正在进行时,我无法真正看到测试完成率等。在任务执行结束时,它只会吐出总运行时间和指向HTML生成报告的链接。这是一个小问题,我完全可以接受它,但如果我能想出如何改进solu,那就太好了使用JUnit runner用户界面的选项。

当问题发布时,这可能是不可能的,但现在您可以在android studio中轻松地完成

我正在使用gradle构建工具:
'com.android.tools.build:gradle:2.2.3'

我在我的root
build.gradle
文件中添加了以下内容

allprojects {
    // ...
    tasks.withType(Test) {
        maxParallelForks = Runtime.runtime.availableProcessors()
    }
}
现在,我有多个
Gradle测试执行器
用于我的测试。运行机器的内核越多,执行器就越多


感谢分享您的原始答案!

顺便说一句,对于那些感兴趣的人来说,运行时间从平均4分钟45秒变为平均2分钟3秒。它没有像预期的那样低的原因是由于单个测试类有很多测试方法,我接受这个作为答案,但是如果您有更好的想法或答案的改进版本(特别是上面用粗体表示的缺点),我会奖励你答案,然后向上投票,谢谢我设置maxParallelForks=8,时间没有减少。你还需要做什么?谢谢你的帖子,但是你的答案和我的有什么不同吗?:)我觉得这个子项目对我不起作用。但我想这取决于你的项目结构。