2013-10-03 40 views
2

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

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倍。但是,我得到了上面的事件日志。为什么会发生?

回答

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(); 
     } 
    } 
} 
}