これは悪い習慣ですが、実行する必要があります。そうしないと、に切り替える必要がありますtestng
。JUnit 3のtestSuiteと同様に、クラスで実行されるテストの順序を指定する方法はありますか?
6 に答える
あなたが本当にこれをやりたいと確信しているなら:もっと良い方法があるかもしれませんが、これが私が思いつくことができるすべてです...
JUnit4にはアノテーションがあります。@RunWith
これにより、テストのデフォルトのランナーをオーバーライドできます。
あなたの場合、の特別なサブクラスを作成し、BlockJunit4ClassRunner
オーバーライドcomputeTestMethods()
して、実行したい順序でテストを返します。たとえば、アルファベットの逆順でテストを実行したいとします。
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class klass) throws InitializationError {
super(klass);
}
@Override
protected List computeTestMethods() {
List list = super.computeTestMethods();
List copy = new ArrayList(list);
Collections.sort(copy, new Comparator() {
public int compare(FrameworkMethod o1, FrameworkMethod o2) {
return o2.getName().compareTo(o1.getName());
}
});
return copy;
}
}
@RunWith(OrderedRunner.class)
public class OrderOfTest {
@Test public void testA() { System.out.println("A"); }
@Test public void testC() { System.out.println("C"); }
@Test public void testB() { System.out.println("B"); }
}
このテストを実行すると、次のようになります。
C B A
特定のケースでは、実行したい順序でテストを名前でソートするコンパレータが必要になります。Ordering.explicit("methodName1","methodName2").onResultOf(...);
( onResultOfがFrameworkMethodをその名前に変換する関数を提供するGoogle Guavaのクラスのようなものを使用してコンパレーターを定義することをお勧めします...もちろん、あなたはそれを好きなように自由に実装できます。
特にJUnitを使用して機能テストを実行したり、永続オブジェクトをテストしたりする場合は、これを行う理由がいくつかわかります。たとえば、Article
ある種の永続ストレージに永続化されているオブジェクトについて考えてみます。Article
単体テストの原則「すべてのテストは並べ替え可能で、機能の特定の部分のみをテストする必要がある」に従って、オブジェクトの挿入、更新、および削除機能をテストする場合、次の3つのテストがあります。
testInsertArticle()
testUpdateArticle()
testDeleteArticle()
ただし、更新機能をテストできるようにするには、最初に記事を挿入する必要があります。削除機能をテストするには、記事を挿入する必要もあります。したがって、実際には、挿入機能はとですでにテストされていtestUpdateArticle()
ますtestDeleteArticle()
。次に、すべてを実行するテストメソッドを作成したくなりますtestArticleFunctionality()
が、そのようなメソッドは最終的には巨大になります(そして、Article
オブジェクトの機能の一部をテストするだけではありません)。
同じことが、たとえばRESTfulAPIに対して機能テストを実行する場合にも当てはまります。JUnitは、テストの順序が不確定でない場合でも、これらのケースに最適です。
そうは言っても、私はMichael Dを拡張OrderedRunner
して、注釈を使用してテストの順序を決定しました。共有する必要があると思っただけです。たとえば、各テストが依存するテストを正確に指定することで、さらに拡張できますが、これは現在私が使用しているものです。
これがその使用方法です。、、、、 ...、などのAA_testInsert()
名前付けテストの必要性を回避します。AB_testUpdate()
AC_testDelete()
ZC_testFilter()
@RunWith(OrderedRunner.class)
public class SomethingTest {
@Test
@Order(order=2)
public void testUpdateArticle() {
// test update
}
@Test
@Order(order=1)
public void testInsertArticle() {
// test insert
}
@Test
@Order(order=3)
public void testDeleteArticle() {
// test delete
}
}
これらのテストがファイルにどのように配置されていても、Eclipse内から、Antを使用して、またはその他の方法で実行するかどうかに関係なく、常にorder=1
最初、order=2
2番目、最後として実行されます。order=3
実装は次のとおりです。まず、注釈Order
。
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
public int order();
}
次に、変更されたOrderedRunner
。
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> copy = new ArrayList<>(super.computeTestMethods());
Collections.sort(list, 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 0;
if (o1 == null) return 1;
if (o2 == null) return -1;
return o1.order() - o2.order();
}
});
return list;
}
}
JUnitバージョン4.11以降では、クラスに注釈を付け@FixMethodOrder
、使用可能ないずれかを指定することで、テストの実行順序に影響を与えることができますMethodSorters
。詳細については、このリンクを参照してください。
新しい注釈を使用junit 4.11
すると、特定の順序を設定できます。 @FixMethodOrder
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
「ソースコードに存在するのと同じように」junitテストを順番に実行し、テストコードを変更したくない場合は、ここでの私のメモを参照してください。
しかし、それは本当に良い考えではありません。テストは独立している必要があります。
JoscarssonとMichaelDのコードは私のgithubリポジトリにあります。彼らが気にしないことを願っています。また、Parameterizedクラスの注文バージョンも提供しています。すでにMavenの依存関係として使用しています
<repositories>
<repository>
<id>git-xxx</id>
<url>https://github.com/crsici/OrderedRunnerJunit4.11/raw/master/</url>
</repository>
</repositories>
<dependency>
<groupId>com.sici.org.junit</groupId>
<artifactId>ordered-runner</artifactId>
<version>0.0.1-RELEASE</version>
</dependency>