web-dev-qa-db-ja.com

JUnitテストのグループ化

JUnitでテストをグループ化する方法はありますか?そのため、いくつかのグループのみを実行できますか?

または、いくつかのテストに注釈を付けて、それらをグローバルに無効にすることは可能ですか?

JUnit 4を使用していますが、TestNGは使用できません。

編集: @RunWithおよび@SuiteClassesは素晴らしい働きをします。しかし、このようにテストクラスのいくつかのテストだけに注釈を付けることは可能ですか?または、テストクラス全体に注釈を付ける必要がありますか?

41
Jakub Arnold

テストクラス内でテストをグループ化しますか、それともテストクラスをグループ化しますか?後者を想定します。

テストの実行方法によって異なります。 Mavenで実行する場合、含めるテストを正確に指定できます。 Maven surefire documentation を参照してください。

ただし、より一般的には、テストスイートのツリーがあるということです。 JUnit 4のテストスイートは次のようになります。

 @RunWith(Suite.class)
 @SuiteClasses({SomeUnitTest1.class, SomeUnitTest2.class})
 public class UnitTestsSuite {
 }

そのため、FunctionTestsSuiteとUnitTestsSuiteがあり、その後、他の2つを含むAllTestsSuiteがあります。 Eclipseで実行すると、非常に素晴らしい階層ビューが得られます。

このアプローチの問題は、テストを複数の異なる方法でスライスしたい場合、退屈なことです。ただし、それでも可能です(たとえば、モジュールに基づいてスライスするスイートのセットを使用し、次にテストのタイプに基づいて別のセットをスライスすることができます)。

8
waxwing

JUnit 4.8はグループ化をサポートしています。

public interface SlowTests {}
public interface IntegrationTests extends SlowTests {}
public interface PerformanceTests extends SlowTests {}

その後...

public class AccountTest {

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeSomeTime() {
        ...
    }

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeEvenLonger() {
        ...
    }

    @Test
    public void thisOneIsRealFast() {
        ...
    }
}

そして最後に、

@RunWith(Categories.class)
@ExcludeCategory(SlowTests.class)
@SuiteClasses( { AccountTest.class, ClientTest.class })
public class UnitTestSuite {}

ここから: https://community.Oracle.com/blogs/johnsmart/2010/04/25/grouping-tests-using-junit-categories-

また、Arquillian自体もグループ化をサポートしています: https://github.com/weld/core/blob/master/tests-arquillian/src/test/Java/org/jboss/weld/tests/Categories.Java =

74
Ondra Žižka

それらをグローバルに無効化するために、JUnit(4.5+)には2つの方法があります1つは、新しいメソッドassumeThatを使用することです。テストクラスの@BeforeClass(または@Before)にそれを配置し、条件が失敗した場合、テストを無視します。条件では、システムプロパティまたはグローバルにオンまたはオフに設定できる何かを配置できます。

他の方法は、グローバルプロパティを理解し、適切なランナーに委任するカスタムランナーを作成することです。このアプローチははるかに脆弱です(JUnit4の内部ランナーは不安定で、リリースごとに変更できるため)が、クラス階層を継承してサブクラスでオーバーライドできるという利点があります。また、レガシーJUnit38クラスをサポートする必要がある場合、これを行う唯一の現実的な方法でもあります。

カスタムランナーを実行するためのコードを次に示します。 getAppropriateRunnerForClassが何をするかについて、私が実装した方法は、カスタムランナーに何を実行するかを伝える別個の注釈を付けることでした。唯一の選択肢は、JUnitコードからの非常に壊れやすいコピーペーストです。

private class CustomRunner implements Runner
 private Runner runner;

    public CustomRunner(Class<?> klass, RunnerBuilder builder) throws Throwable {
        if (!isRunCustomTests()) {
            runner = new IgnoredClassRunner(klass);
        } else {
            runner = getAppropriateRunnerForClass(klass, builder);
    }

    public Description getDescription() {
        return runner.getDescription();
    }

    public void run(RunNotifier notifier) {
        runner.run(notifier);
    }
}

編集:@RunWithタグはクラス全体に対してのみ機能します。その制限を回避する1つの方法は、テストメソッドを静的な内部クラスに移動して、注釈を付けることです。そうすれば、クラスの編成でアノテーションの利点が得られます。ただし、それを行っても@Beforeタグまたは@BeforeClassタグでは役に立たないため、内部クラスでそれらを再作成する必要があります。外部クラスのメソッドを呼び出すことができますが、独自のメソッドをフックとして持つ必要があります。

10
Yishai

JUnit 5では、クラスレベルまたはメソッドレベルで、テストのフィルタリング用に_@Tag_を宣言できます。 TestNGのテストグループまたはJUnit 4のカテゴリに類似

javadoc から:

タグは、特定のテスト計画に対して実行されるテストをフィルタリングするために使用されます。たとえば、開発チームは、テストに「fast」、「slow」、「ci-server」などの値をタグ付けし、現在のテスト計画に使用されるタグのリストを提供します。環境。

たとえば、すべてのメソッドに継承される_"slow"_ _@Tag_を使用してテストクラスを宣言し、必要に応じて一部のメソッドにオーバーライドできます。

_import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Tag("slow") 
public class FooTest{

   // 
   @Test
   void loadManyThings(){ 
        ...
   }

   @Test
   void loadManyManyThings(){ 
        ...
   }


   @Test
   @Tag("fast")
   void loadFewThings(){ 
        ...
   }

}
_

同じロジックを他のテストクラスに適用できます。
このようにして、テストクラス(およびメソッド)も特定のタグに属します。

テストクラス全体で@Tag("fast")および@Tag("slow")をコピーして貼り付ける代わりに、カスタム合成アノテーションを作成することをお勧めします。
例えば :

_import Java.lang.annotation.ElementType;
import Java.lang.annotation.Retention;
import Java.lang.annotation.RetentionPolicy;
import Java.lang.annotation.Target;

import org.junit.jupiter.api.Tag;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("slow")
public @interface Slow {
}
_

そしてそれを次のように使用します:

_@Test
@Slow
void slowProcessing(){ 
    ...
}   
_

テキストの実行中に特定のタグでマークされたテストを有効または無効にするには、 maven-surefire-plugin documentation に依存できます。

タグまたはタグ式を含めるには、groupsを使用します。

タグまたはタグ式を除外するには、excludedGroupsを使用します。

要件に応じてpom.xmlでプラグインを構成するだけです(ドキュメントの例):

_ <build>
     <plugins>
         ...
         <plugin>
             <groupId>org.Apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
             <version>2.22.0</version>
             <configuration>
                 <groups>acceptance | !feature-a</groups>
                 <excludedGroups>integration, regression</excludedGroups>
             </configuration>
         </plugin>
     </plugins> 
</build> 
_

詳細については、 テスト目標のドキュメント は更新されていません。

3
davidxxx

JUnit Test Groups を試してください。ドキュメントから:

@TestGroup("integration")
public class MyIntegrationTest {
   @ClassRule
   public static TestGroupRule rule = new TestGroupRule();

   ...
}
  • 簡単なテストグループを実行します。-Dtestgroup = integration
  • 複数のテストグループを実行します。-Dtestgroup = group1、group2
  • すべてのテストグループを実行します。-Dtestgroup = all
3
Bit-Man

テストを作成できます Suite テストのグループを含むオブジェクト。あるいは、IDE(Eclipseのような)は、与えられたパッケージに含まれるすべてのテストの実行をサポートするかもしれません。

1
Kevin

テストスイートを使用できます( http://qaautomated.blogspot.in/2016/09/junit-test-suits-and-test-execution.html )またはJunitカテゴリ( http://qaautomated.blogspot.in/2016/09/junit-categories.html )テストケースを効果的にグループ化するため。

0
anuja jain