1

次のカスタムBlockJUnit4ClassRunnerを作成しました

  public class RepeatEachTest extends BlockJUnit4ClassRunner {

  private int repeats;

  public RepeatEachTest(Class<?> klass) throws InitializationError {
    super(klass);
    Repeat r = klass.getAnnotation(Repeat.class);
    if (r == null) {
        throw new InitializationError("A @Repeat annonation must also be suplied to class, for example @Repeat(5) to repeat 5 times");
    }
    repeats = r.value();
  }

  @Override
  protected void runChild(FrameworkMethod method, RunNotifier notifier) {
    for (int i = 0; i < repeats; i++) {
        super.runChild(method, notifier);
    }
  }

  @Override
  public int testCount() {
    return repeats * super.testCount();
  }
}

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

テスト@Repeat.value()を何度も実行します。のテスト実行

@RunWith(RepeatEachTest.class)
@Repeat(2)
public class RepeatEachTestTest {

  @Test
  public void first() {
    System.out.println("ran first");
  }

  @Test
  public void second() {
    System.out.println("ran second");
  }
}

のように見えます

ran first
ran first
ran second
ran second

しかし、今度は、テストクラス全体を何度も実行する2番目のBlockJUnit4ClassRunnerを実装したいと思います。そのセットアップからの実行は次のようになります @Repeat.value()

ran first
ran second
ran first
ran second

何かご意見は?

4

1 に答える 1

1

それはあなたが望むものに依存します。@BeforeClassand@AfterClassメソッドとクラスルールを複数回呼び出す場合は、以下をオーバーライドできますclassBlock()

protected Statement classBlock(final RunNotifier notifier) {
  return new Statement() {
    @Override
    public void evaluate() throws Throwable {
      for (int i = 0; i < repeats; i++) {
        super.classBlock(notifier).evaluate();
      }
    }
  };
}

@BeforeClassand@AfterClassメソッドとクラスルールを1回呼び出す場合は、オーバーライドします(childrenInvoker()コードは類似しています)。

ただし、これらのいずれかを実行すると、テストが開始および完了したことがリスナーに複数回通知されることに注意してください。この状況では、一部のリスナーが正しく動作しない場合があります。

于 2013-03-06T08:03:29.090 に答える