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

时间:2019-02-26 10:41:23

标签: java unit-testing junit test-suite

我有以下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 {
}

这有两个测试类。 MakeBookingTest PaymentTest 。他们每个人都有多个JUnit测试。

如果它们失败,我希望重试它们。知道如何实现吗?

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

2 个答案:

答案 0 :(得分:1)

首先,我同意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();
    }
}

答案 1 :(得分:0)

基于给出的评论,一个独特的非答案:

  

有时会失败,因为它们可能是亚麻。但是99%的时间,如果我重新运行...它是可行的。

在这种情况下,花费时间和精力以说服您的测试设备进行“重新运行” ...很可能是一笔错误的投资。

您的问题不是重试。您的实际问题是您的测试不稳定。您将所有的时间和精力都投入到理解原因为何测试不可靠的原因上,然后修复该问题。

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