本文参考:https://junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution
默认情况下,junit测试是在一个线程中串行执行的,从5.3开始支持并行测试。首先需要在配置文件junit-platform.properties
中配置如下参数:
junit.jupiter.execution.parallel.enabled=true
但是仅仅开启这个参数是不会起效的,测试仍然是按照单个线程去执行的。在测试树上的每个节点是否并发执行是通过执行的模式来决定的。有以下两种可以选择的模式:
SAME_THREAD
强制使用同一个线程
CONCURRENT
并发执行(除非某个锁资源导致的串行操作)
默认情况下,测试树上的节点使用的是SAME_THREAD执行模式,可以通过修改默认的配置。如下:
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
配置的默认执行模式会作用于测试树上的每个节点,但是有几个需要主要的例外。首先就是针对于测试声明周期的配置(默认是方法级别的)如果设置为类级别(Lifecycle.PER_CLASS
)则必须保证测试类是线程安全的,另外对于设置测试方法的执行顺序(MethodOrderer
(Random模式例外))的话,这个与并发测试是互相矛盾的。在以上这两种情况下,必须明确在测试类或方法上面添加注解@Execution(CONCURRENT)
,否则也不会按照并发模式进行测试的。
采用以上的模式,所有的测试类和测试方法都是并发来执行的。
当然还可以通过另外一个配置来保证类是并行测试而内部方法是串行测试的,比如设置类之间并行和方法之间串行
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = same_thread
junit.jupiter.execution.parallel.mode.classes.default = concurrent
设置类之间串行而内部方法是并行的
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
junit.jupiter.execution.parallel.mode.classes.default = same_thread
以上两个配置并行和串行的参数对应的四种情况如下所示:
如果junit.jupiter.execution.parallel.mode.classes.default
没有明确配置的话,则按照junit.jupiter.execution.parallel.mode.default
的值。
以下进行测试:
首先引入junit5的依赖配置
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-commons -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-engine -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
编写两个测试类。每个测试类中有两个测试方法
package com.example.project;
import org.junit.jupiter.api.Test;
/**
* Created in 2020/6/28 19:07 by guanglai.zhou
*/
public class TestClassOne {
@Test
public void testMethodOne() {
System.out.println(this.getClass() + "-testMethodOne-" + Thread.currentThread().getName());
}
@Test
public void testMethodTwo() {
System.out.println(this.getClass() + "-testMethodTwo-" + Thread.currentThread().getName());
}
}
package com.example.project;
import org.junit.jupiter.api.Test;
/**
* Created in 2020/6/28 19:07 by guanglai.zhou
*/
public class TestClassTwo {
@Test
public void testMethodOne() {
System.out.println(this.getClass() + "-testMethodOne-" + Thread.currentThread().getName());
}
@Test
public void testMethodTwo() {
System.out.println(this.getClass() + "-testMethodTwo-" + Thread.currentThread().getName());
}
}
在资源目录下编写配置文件junit-platform.properties
,默认情况
# 此时不配置
执行测试 ,可以看到只有一个线程 main
开启配置
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
可以看到此时出现了多个work线程。
另外还有两个参数可用于配置线程池的大小也就是并发度,如下配置了固定2个线程的线程池
# the maximum pool size can be configured using a ParallelExecutionConfigurationStrategy
junit.jupiter.execution.parallel.config.strategy=fixed
junit.jupiter.execution.parallel.config.fixed.parallelism=2