预期超时的 JUnit 测试

2022-09-03 02:21:55

我对TCP套接字的通信进行了测试,我希望服务器在发送特定消息时不会在设定的时间范围内响应。

服务器的行为是我无法控制的。

我知道如果测试未在设定的时间范围内完成,该如何通过测试。但是,我该怎么做才能反其道而行之,让它在时间范围内没有完成呢?

如果测试没有在一秒钟内完成,我可以用来使测试失败。@Test (timeout=1000)

但是,使用 Junit 4,是否有函数来测试预期超时作为阳性结果?即,如果在时间范围内完成测试,测试将失败,否则通过?


答案 1

问得好。实际上,您只能使用工具执行此操作。我的想法是逆规则行为+使用注释的属性。唯一的一个限制是:您必须将测试放在单独的类中,因为该类适用于所有测试:junitTimeoutexpectedTestRule

public class Q37355035 {

    private static final int MIN_TIMEOUT = 100;

    @Rule
    public Timeout timeout = new Timeout(MIN_TIMEOUT) {
        public Statement apply(Statement base, Description description) {
            return new FailOnTimeout(base, MIN_TIMEOUT) {
                @Override
                public void evaluate() throws Throwable {
                    try {
                        super.evaluate();
                        throw new TimeoutException();
                    } catch (Exception e) {}
                }
            };
        }
    };

    @Test(expected = TimeoutException.class)
    public void givesTimeout() throws InterruptedException {
        TimeUnit.SECONDS.sleep(1);
    }
}

答案 2

我正在建立安德烈莫尼的伟大答案,如果你喜欢这个,别忘了投票给他的答案!

我使用以下修改来跳过测试,如果它没有在预期的时间范围内完成。这样做的好处是,测试将被标记为 JUnit 跳过,而不是成功。这有利于乐观地执行测试,这些测试有时会挂起或完成得不够快,但您不想将它们标记为失败或删除它们。

public class OptimisticTestClass {

    private static final int TEST_METHOD_TIMEOUT_MS = 100;

    @Rule
    public Timeout timeout = new Timeout(TEST_METHOD_TIMEOUT_MS, TimeUnit.MILLISECONDS) {
        public Statement apply(Statement base, Description description) {
            return new FailOnTimeout(base, TEST_METHOD_TIMEOUT_MS) {
                @Override
                public void evaluate() throws Throwable {
                    try {
                        super.evaluate();
                    } catch (TestTimedOutException e) {
                        Assume.assumeNoException("Test did not finish in the allocated time, skipping!", e);
                    }
                }
            };
        }
    };

    // The test times out and is skipped
    public void givesTimeout() throws InterruptedException {
        Thread.sleep(1000);
    }
}

推荐