繁体   English   中英

如果失败,如何在 SuiteClass 中重试 JUnit 测试?

[英]How to make a JUnit Test retry in SuiteClass if it fails?

我有以下 RetryRule 类:

public class RetryRule implements TestRule {
    private int retryCount;

    public RetryRule(int retryCount) {
        this.retryCount = retryCount;
    }

    public Statement apply(Statement base, Description description) {
        return statement(base, description);
    }

    private Statement statement(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                Throwable caughtThrowable = null;

                for (int i = 0; i < retryCount; i++) {
                    try {
                        base.evaluate();
                        return;
                    }
                    catch (Throwable t) {
                        caughtThrowable = t;
                        System.err.println(description.getDisplayName() + ": run " + (i + 1) + " failed.");
                    }
                }
                System.err.println(description.getDisplayName() + ": giving up after " + retryCount + " failures.");
                if (caughtThrowable != null) {
                    throw caughtThrowable;
                }
            }
        };
    }
}

以及以下 SuiteClass:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
MakeBookingTest.class,
PaymentTest.class
})

public class TestSuite {
}

这有两个测试类.. MakeBookingTestPaymentTest 他们每个人都有多个 JUnit 测试。

我希望他们在失败时重试。 知道我如何实现它吗?

编辑:为了更好地理解,您可以使用我的代码来举例说明要添加的内容。 谢谢。 欣赏它。

首先,我同意 GhostCat。
Flakey 测试代码才是真正的问题。

但是,如果“ flakeyness ”不在您的代码中(例如,与外部 Web 服务的网络连接不良),那么重新运行测试会很有用。

在这种情况下,您可以执行以下操作。

首先创建一个接口注解。 (这将用于指示哪些测试需要重试。)

@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {}

然后在我们的测试中应用一个TestRule (如果存在Retry注释,此规则将检查失败)

public class RetryRule implements TestRule {
    @Override
    public Statement apply(Statement base, Description method) {
        return new Statement() {
            @Override 
            public void evaluate() throws Throwable {
                try {
                    base.evaluate();
                } catch (Throwable t) {
                    Retry retry = method.getAnnotation(Retry.class);
                    if (retry != null) {
                        base.evaluate();
                    } else {
                        throw t;
                    }
                }
            }
        };
    }
}

最后在我们的测试中我们把所有东西放在一起

public class RetryTest {
    private static int count = 0;

    @Rule
    public RetryRule rule = new RetryRule();

    @Test
    @Retry
    public void testToRetry() throws Exception {
        callMyFlakeyCode();
    }
}

根据给出的评论,一个明显的非答案:

有时它会失败,因为它们可能很脆弱。 但是 99% 的时间,如果我重新运行......它会起作用。

在这种情况下,投入时间和精力以说服您的测试设置进行“重新运行”……很可能是:一项糟糕的投资。

你的问题不是重试。 真正的问题是你有不稳定的测试。 您将所有时间和精力投入到了解测试不可靠的原因上,然后解决该问题。

其他任何事情都无缘无故地增加了设置的复杂性。 您编写需要维护的特殊代码,更糟糕的是:所有未来的读者都必须理解“是的,这些测试在那里,我们只是重试直到它们通过”。 这是人们迟早会接受的信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM