JUnit 実行順序を指定するだけだと、
JUnit テストケースの実行順序 - Oboe吹きプログラマの黙示録
この通りだが、さらにその実行順序を振った前提で順番の番号の範囲を指定して
実行するにはこれに、少し改良すれば良い
@Order アノテーションは前回と同じ
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Order */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Order { int value(); }
加えて新たに、テストクラスに付与させる実行順序番号による範囲を指定する
アノテーション
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * TestRange */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TestRange { int start() default 1; int end() default 0; }
そして、BlockJUnit4ClassRunnerを継承したソートを以下のように改良する。
import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; /** * OrderedRunner */ public class OrderedRunner extends BlockJUnit4ClassRunner { private TestRange range; public OrderedRunner(Class<?> cls) throws InitializationError { super(cls); range = cls.getAnnotation(TestRange.class); } @Override protected List<FrameworkMethod> computeTestMethods() { List<FrameworkMethod> list = super.computeTestMethods(); if (range==null) { return list.stream().sorted(new Comparator<FrameworkMethod>(){ @Override public int compare(FrameworkMethod f1, FrameworkMethod f2){ Order o1 = f1.getAnnotation(Order.class); Order o2 = f2.getAnnotation(Order.class); if (o1==null || o2==null){ return -1; } return o1.value() - o2.value(); } }).collect(Collectors.toList()); } List<FrameworkMethod> res = list.stream().sorted(new Comparator<FrameworkMethod>(){ @Override public int compare(FrameworkMethod f1, FrameworkMethod f2){ Order o1 = f1.getAnnotation(Order.class); Order o2 = f2.getAnnotation(Order.class); if (o1==null || o2==null){ return -1; } return o1.value() - o2.value(); } }).collect(Collectors.toList()); int end = range.end()==0 ? res.size() : range.end(); return IntStream.rangeClosed(range.start(), end).boxed().map(i->res.get(i-1)).collect(Collectors.toList()); } }
@Order(10) から @Order(19) を実行したい場合
@RunWith(OrderedRunner.class) @TestRange(start=10, end=19) public class SampleTest{
@Order(20) 以降を実行したい場合
@RunWith(OrderedRunner.class) @TestRange(start=20) public class SampleTest{
@Order(30) までを実行したい場合
@RunWith(OrderedRunner.class) @TestRange(end=30) public class SampleTest{
これで、大量に作成したテストケースを一時的に任意の範囲で実行したい時は、
クラスアノテーション @TestRange で指定できる。
範囲指定しないで全て順番どおりに実行するときは、 @TestRangeをコメントアウトにすればよい。