最多重复每次测试N次,直到第一次成功

时间:2016-07-06 18:55:18

标签: spring testing junit

我的JUnit测试用

注释
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations=...

每个单独测试失败的概率非常低。然而,由于大量测试,所有测试成功的概率,即通过自动测试的概率也很低。一旦知道测试功能正确实现(测试失败,它们总是失败,因为功能未正确实现,或者由于某些条件的组合,它们偶尔会失败),测试成功就足够了。测试环境,很少发生。)

所以我需要的是,对于固定的N,最多重复每次测试N次直到成功。只有当测试失败了N次时,我才推断必须要打破一些东西。

可以建议一种干净的方式来实现它(可能是其他方式的子类化Spring JUnit运行器吗?)

1 个答案:

答案 0 :(得分:0)

这是一个似乎有效的基本实现(一个注释测试类,测试方法将重复,直到成功@CustomJUnit4ClassRunner而不是@SpringJUnit4ClassRunner):

import org.junit.internal.runners.model.ReflectiveCallable;
import org.junit.internal.runners.statements.Fail;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

public class CustomJUnit4ClassRunner extends SpringJUnit4ClassRunner {

    public CustomJUnit4ClassRunner(Class<?> clazz)
            throws InitializationError {
        super(clazz);
    }

    @Override
    protected Statement methodBlock(FrameworkMethod frameworkMethod) {
        Object testInstance;
        try {
            testInstance = new ReflectiveCallable() {

                @Override
                protected Object runReflectiveCall() throws Throwable {
                    return createTest();
                }
            }.run();
        }
        catch (Throwable ex) {
            return new Fail(ex);
        }

        Statement statement = methodInvoker(frameworkMethod, testInstance);
        statement = possiblyExpectingExceptions(frameworkMethod, testInstance, statement);
        statement = withBefores(frameworkMethod, testInstance, statement);
        statement = withAfters(frameworkMethod, testInstance, statement);
        //statement = withRulesReflectively(frameworkMethod, testInstance, statement);
        //statement = withPotentialRepeat(frameworkMethod, testInstance, statement);
        statement = withPotentialTimeout(frameworkMethod, testInstance, statement);
        statement = withRepeatUntilSuccess(frameworkMethod, testInstance, statement);

        return statement;
    }

    private Statement withRepeatUntilSuccess(FrameworkMethod frameworkMethod, Object testInstance, Statement next) {
        return new CustomTestRepeat(next, frameworkMethod.getMethod(), Constants.MAX_NUM);
    }

}

与以下课程一起

import java.lang.reflect.Method;

import org.junit.runners.model.Statement;

public class CustomTestRepeat extends Statement {

    private final Statement next;

    private final Method testMethod;

    private final int repeat;

    public CustomTestRepeat(Statement next, Method testMethod, int repeat) {
        this.next = next;
        this.testMethod = testMethod;
        this.repeat = Math.max(1, repeat);
    }

    @Override
    public void evaluate() throws Throwable {
        for (int i = 0; i < this.repeat - 1; i++) {
            try {
                this.next.evaluate();
            }
            //Assertion errors are not instances of java.lang.Exception
            catch (Throwable e) {
                continue;
            }
            return;
        }
        this.next.evaluate();
    }
}