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

6rqinv9w  于 2022-12-22  发布在  其他
关注(0)|答案(3)|浏览(171)
    • 问题**

我有一堆junit测试(许多都有自定义的运行程序,如PowerMockRunner或JUnitParamsRunner),它们都在某个根包tests下(它们在tests的不同子包中,处于不同的深度)。
我想收集包tests下的所有测试,并在不同的JVM中并行运行每个测试类。理想情况下,并行化是可配置的,但默认的number_of_cores也完全可以。注意,我不想在自己的JVM中运行每个方法,而是每个类。

    • 背景**

我通过注解@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(JUnitParamsRunner.class)将PowerMock与JUnitParams结合使用来进行许多测试。我有大约9000个单元测试,它们在"OK"时间内完成,但我有一个8核CPU,系统在默认的一次一个测试运行程序下严重利用不足。由于我经常运行测试,额外的时间加起来,我真的想并行运行测试类。
请注意,不幸的是,在大量测试中,我需要模拟静态方法,这也是我使用PowerMock的部分原因。
"我所尝试的"
必须模拟静态方法使得不可能使用com.googlecode.junittoolbox.ParallelSuite之类的东西(这是我最初的解决方案),因为它在同一个JVM中运行所有东西,静态模拟变得交错和混乱。至少根据我得到的错误,我认为是这样的。
我根本不知道JUnit堆栈,但在四处查看之后,我发现另一种选择可能是尝试编写和注入我自己的RunnerBuilder--但我甚至不确定是否可以从RunnerBuilder中生成另一个JVM进程,这不太可能。我认为适当的解决方案是某种作为gradle任务存在的工具。
我也刚刚发现了一些Android Studio(Intellij's)测试选项,但唯一可用的fork选项是method,这不是我想要的。我目前正在探索这个解决方案,所以也许我会弄清楚,但我想我会问社区并行,因为我还没有太多的锁。

    • 更新**:终于能够让Android Studio(Intellij)使用选项收集我的所有测试测试类型:All in directory(由于某些原因,包选项没有执行递归搜索)和选择fork模式Class。但是,这仍然会按顺序运行每个找到的测试类,并且没有看到关于并行化的选项。这非常接近我想要的,但不完全...:(
xt0899hw

xt0899hw1#

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

subprojects {
    tasks.withType(Test) {
        maxParallelForks = Runtime.runtime.availableProcessors()
    }
}

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

此解决方案的缺点是无法与Android Studio的(Intellij)漂亮的junit runner UI。因此,当gradle任务正在进行时,我无法真正看到测试完成的速度等。在任务执行结束时,它只会显示总运行时间和一个指向HTML生成的报告的链接。这是一个次要问题,我完全可以接受。但如果我能弄清楚如何改进解决方案以使用JUnit runner UI,那就太好了。

whitzsjs

whitzsjs2#

也许这在问题发布的时候是不可能的,但现在你可以在android studio中很容易地做到。
我正在使用Gradle构建工具:第一个月
我在根build.gradle文件中添加了以下内容。

allprojects {
    // ...
    tasks.withType(Test) {
        maxParallelForks = Runtime.runtime.availableProcessors()
    }
}

现在,我有多个Gradle Test Executor运行程序用于我的测试。您运行的机器的内核越多,您拥有的执行器就越多!
感谢分享您的原始答案!

oxf4rvwz

oxf4rvwz3#

这听起来可能违反直觉,但实际上运行较少数量的fork可能比运行所有可用内核更快
对我来说,与所有可用的处理器(8核CPU,16个线程)相比,对于相同的测试,这种设置快了30秒(1:50而不是2:20)

subprojects {
    tasks.withType(Test) {
        maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
    }
}

相关问题