Junit5超时处理
JUnit5 超时处理
简介
JUnit 5 提供了超时处理功能,用于设置测试方法的最大执行时间。如果测试方法的执行时间超过指定的超时时间,JUnit 5 将中断测试方法的执行,并将其标记为失败。
- 测试过程中如果某条测试用例执行过程中阻塞,就会发生超时问题。
- 阻塞其他用例的执行。
- 对于某些用例,如果用例执行时间过长,超出正常执行范围,用例本身可能存在问题。
使用场景
- 使用 JUnit5 自带的超时处理。当测试用例执行时间超过设置的执行时间,那么用例结果为执行失败。
@Timeout 注解
1. 单独使用 Timeout 注解
- 使用
@Timeout(5)注解配置超时时间,括号中的参数为设置的超时时间,单位为秒,而强制等待 sleep()单位为毫秒。 -
代码实例
package junit5.timeout; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import static java.lang.Thread.sleep; public class TimeoutExampleTest { @Test //设定用例执行的超时时间,一旦超过x秒,则用例失败 @Timeout(3)//单位为秒 void timeoutDemo1() throws InterruptedException { sleep(10000);//单位为毫秒,强制等待10秒,超出超时时间,测试失败 System.out.println("超时用例1"); } @Test @Timeout(3)//单位为秒 void timeoutDemo2(){ System.out.println("超时用例2");//正常执行时间在3s内,测试通过 } }
- timeoutDemo1 方法中强制等待 10 秒钟,而我们设定的超时时间为 3 秒,运行超时,测试不通过,而 timeoutDemo2 方法正常执行时间在 3 秒之内,测试通过。

2.@Timeout 注解结合@BeforeEach与@AfterEach注解
- 我们依旧沿用上方的代码,先添加
@BeforeEach注解@Timeout注解结合@BeforeEach注解- 代码示例
@BeforeEach//在每次测试执行之前执行 @Timeout(3)//设定用例执行的超时时间,一旦超过3秒,则用例失败 void setup() throws InterruptedException { sleep(40000);//强制等待4秒 System.out.println("开始测试"); } - 未添加
@BeforeEach注释之前的测试方法执行结果如上图,timeoutDemo1方法未通过,timeoutDemo2方法通过;添加@BeforeEach注释后,两个测试方法均未通过,原因是我们在set up方法中强制等待的时间超出了超时时间,所以原本可以通过的timeoutDemo2方法也失败了。

- 将 setup 方法中的强制等待时间注释,再执行查看结果,可以观察到,将等待时间注释之后,测试方法正常执行。所以@Timeout 注解结合
@BeforeEach结合使用可以在创建测试所需的对象、初始化数据时测试超时时间。
-
在之前代码的基础上,添加
@AfterEach注解@Timeout注解结合@AfterEach注解- 代码示例
@AfterEach @Timeout(3) void teardown() throws InterruptedException { sleep(40000); System.out.println("结束测试"); }- 添加
@AfterEach注释在 teardown 方法中添加等待时间,两个测试方法均未通过,timeoutDemo1方法失败的原因是方法执行时超出了超时时间,原本可以通过的timeoutDemo2方法失败是因为 teardown 函数执行超时。

- 将 teardown 方法中的强制等待时间注释,再执行查看结果,可以观察到,将等待时间注释之后,测试方法正常执行。所以@Timeout 注解结合
@BeforeEach结合使用可以在回收数据,进行数据清洗等操作时测试超时时间。
-
代码实例
package junit5.timeout; import org.junit.jupiter.api.*; import static java.lang.Thread.sleep; public class TimeoutExampleTest { @BeforeEach//在每次测试执行之前执行 @Timeout(3)//设定用例执行的超时时间,一旦超过3秒,则用例失败 void setup() throws InterruptedException { //sleep(40000);//强制等待4秒 System.out.println("开始测试"); } @AfterEach @Timeout(3) void teardown() throws InterruptedException { sleep(40000); System.out.println("结束测试"); } @Test //设定用例执行的超时时间,一旦超过x秒,则用例失败 @Timeout(3)//单位为秒 void timeoutDemo1() throws InterruptedException { sleep(10000);//单位为毫秒,强制等待10秒,超出超时时间,测试失败 System.out.println("超时用例1"); } @Test @Timeout(3)//单位为秒 void timeoutDemo2(){ System.out.println("超时用例2");//正常执行时间在3s内,测试通过 } }
@Timeout 注解时间单位配置表
@Timeout注解的默认超时时间单位为秒(s),除此之外还可以手动设置时间单位。
| 时间 | 配置内容 |
| ---------- | ------------ |
| 42 毫秒 | @Timeout(value = 42, unit = MILLISECONDS) |
| 42 秒 | @Timeout(value = 42, unit = SECONDS) |
| 42 分 | @Timeout(value = 42, unit = MINUTES) |
| 42 小时 | @Timeout(value = 42, unit = HOURS) |
| 42 天 | @Timeout(value = 42, unit = DAYS) |
配置时间单位
- 接下来以
MILLISECONDS为时间单位为例,在@Timeout注解中添加时长和单位。
@Test
//`TimeUnit.MILLISECONDS` 和 `MILLISECONDS` 的本质是相同的,都代表时间单位是毫秒,这里使用效果无差别。
@Timeout(value = 3, unit = TimeUnit.MILLISECONDS)
void failsIfExecutionTimeExceeds100Milliseconds() {
}
- 测试方法中没有需要执行的操作,所以执行时间在超时范围内,测试通过。

- 在测试方法中添加等待时间,再次执行对比结果,可以看到测试方法中等待时间已经为 5 毫秒,超出我们要求的超时时间,测试失败。

-
代码实例
package junit5.timeout; import org.junit.jupiter.api.*; import java.util.concurrent.TimeUnit; import static java.lang.Thread.sleep; public class TimeoutExampleTest { // 如果超过5秒则执行失败 @BeforeEach @Timeout(5) void setUp() { } // 通过value参数配置数量,通过unit参数配置时间单位 @Test //`TimeUnit.MILLISECONDS` 和 `MILLISECONDS` 的本质是相同的,都代表时间单位是毫秒,这里使用效果无差别。 @Timeout(value = 3, unit = TimeUnit.MILLISECONDS) void failsIfExecutionTimeExceeds100Milliseconds() throws InterruptedException { sleep(5);//这里等待的时间单位是毫秒 } }