JUnit 测试超时 – JUnit5 超时示例

JUnit 测试超时 – JUnit5 超时示例

原文: https://howtodoinjava.com/junit/how-to-force-timeout-in-jnuit-testcase-execution/

学习编写具有超时行为的 JUnit 测试。 如果任何测试未在给定的时限内完成执行,则 JUnit 将停止执行。 还学习使用断言使用 JUnit5 测试超时

1. 为什么要编写 JUnit 超时测试?

有时,我们必须编写 JUnit 测试,以访问网络上的某些外部系统。 绝对不能 100% 地确定在执行测试用例时这些外部系统将可用。 这就是为什么在编写具有外部依赖项的测试用例时,建议使用 JUnit 框架的timeout属性。

这也被认为是 JUnit 最佳实践

每个 JUnit 测试都在一个新线程中运行。 如果在测试完成之前经过了指定的超时,则将通过Thread.interrupt()中断其执行。

2. JUnit 测试超时示例 – timeout属性

为了指定某个测试用例的超时周期,在注解@Test上提到“timeout”属性。 例如,@Test(timeout = 1000)

超时时间以毫秒指定。

@Test(timeout = 500)
public void testInfiniteTametakingLoop() throws InterruptedException 
{
	while (true)
	{
		Thread.currentThread().sleep(1000);
	}
}

在上述测试中,执行将在 5 秒后超时,并显示以下消息。

java.lang.Exception: test timed out after 5000 milliseconds

2. JUnit 全局超时示例 – 超时规则

可以为类中的所有测试定义 JUnit 规则,而不是为所有测试分别指定超时属性。

@Rule
public Timeout globalTimeout = Timeout.seconds(2);

@Test 	//Pass
public void testInfiniteTametakingLoop1() throws InterruptedException 
{
	while (true)
	{
		Thread.currentThread().sleep(1000);
	}
}

@Test 	//Fail
public void testInfiniteTametakingLoop2() throws InterruptedException 
{
	while (true)
	{
		Thread.currentThread().sleep(5000);
	}
}

在上面的示例中,第一个测试将通过,而第二个测试将失败。

请注意,以上超时时间@Rule同样适用于@Before@After方法。 因此,请小心使用。

4. 使用断言的 JUnit5 超时

JUnit5 中,我们可以使用断言强制测试超时。

import static java.time.Duration.ofMillis;
import static java.time.Duration.ofMinutes;
import static org.junit.jupiter.api.Assertions.assertTimeout;

@Test
void timeoutNotExceeded() 
{
    //The following assertion succeeds.
    assertTimeout(ofMinutes(2), () -> {
        // Perform task that takes less than 2 minutes.
    });
}

@Test
void timeoutExceeded() 
{
    // The following assertion fails with an error message similar to:
    // execution exceeded timeout of 10 ms by 91 ms
    assertTimeout(ofMillis(10), () -> {
        // Simulate task that takes more than 10 ms.
        Thread.sleep(100);
    });
}

学习愉快!