JUnit重复注释不会启动测试用例

时间:2013-10-03 21:48:23

标签: java junit

我有一个@Repeat注​​释,用于重复运行JUnit测试。代码取自此博客文章here,并已修改为与JUnit 4.10一起运行。

Repeat.java

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Repeat {
    int value();
}

ExtendedRunner.java

public class ExtendedRunner extends BlockJUnit4ClassRunner {

    public ExtendedRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected Description describeChild(FrameworkMethod method) {
        if (method.getAnnotation(Repeat.class) != null &&
                method.getAnnotation(Ignore.class) == null) {
            return describeRepeatTest(method);
        }
        return super.describeChild(method);
    }

    private Description describeRepeatTest(FrameworkMethod method) {
        int times = method.getAnnotation(Repeat.class).value();

        Description description = Description.createSuiteDescription(
                testName(method) + " [" + times + " times]",
                method.getAnnotations());

        for (int i = 1; i <= times; i++) {
            Description d = Description.createSuiteDescription("[" + i + "] " + testName(method));
            d.addChild(Description.createTestDescription(getTestClass().getJavaClass(), testName(method)));
            description.addChild(d);
        }
        return description;
    }

    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {

        if (method.getAnnotation(Repeat.class) != null) {

            if (method.getAnnotation(Ignore.class) == null) {
                Description description = describeRepeatTest(method);
                runRepeatedly(methodBlock(method), description, notifier);
            }
            return;
        }

        super.runChild(method, notifier);
    }

    private void runRepeatedly(Statement statement, Description description,
                               RunNotifier notifier) {
        for (Description desc : description.getChildren()) {
            runLeaf(statement, desc, notifier);
        }
    }

}

最后,测试运行wat() 10次:

@RunWith(ExtendedRunner.class)
public class RepeatTest {

    private int counter = 0;

    @Repeat(10)
    @Test
    public void wat() {
        System.out.println(counter++);
    }
}

当我运行测试时,我在事件日志中得到以下内容。

Failed to start: 9 passed, 1 not started

这也是:

enter image description here

有趣的是,测试打印从0到9,这让我相信测试实际上运行了10次。然而,我得到了上面的事件日志。为什么会这样?

1 个答案:

答案 0 :(得分:0)

我在GitHub上发布了一个重复测试的@Rule。此解决方案比使用Runner更灵活,因为它不排除使用另一个Runner

RepeatTest Rule

RepeatFailingTest Rule

@ThreadSafe
@ParametersAreNonnullByDefault
public class RepeatTest implements TestRule {

public static RepeatTest findRepeats() {
    return new RepeatTest();
}

private RepeatTest() {
    super();
}

@Override
public Statement apply(final Statement statement, Description description) {
    return new StatementRepeater(statement, description);
}

private final class StatementRepeater extends Statement {

    private final Statement statement;
    private final int repeatCount;

    private StatementRepeater(Statement statement, Description description) {
        super();
        this.statement = statement;
        Repeat repeat = description.getAnnotation(Repeat.class);
        this.repeatCount = getRepeatCount(repeat);
    }

    private final int getRepeatCount(@Nullable Repeat repeat) {
        int count = 1;
        if (repeat != null) {
            count = repeat.count();
        }

        assertThat("Repeat count must be > 0", count,
                OrderingComparison.greaterThan(0));
        return count;
    }

    @Override
    public void evaluate() throws Throwable {
        for (int i = 0; i < repeatCount; i++) {
            statement.evaluate();
        }
    }
}
}