1. ホーム
  2. unit-testing

[解決済み] Junit: 統合テストと単体テストの分割

2022-06-20 02:31:16

質問

私はJunitのテストのロードを継承していますが、これらのテストは(ほとんどが機能していないことを除けば)実際のユニットテストと統合テスト(外部システム、データベースなどを必要とする)が混在しています。

そこで、私は実際にそれらを分離する方法を考えようとしています。そうすれば、ユニットテストをうまくかつ迅速に実行し、その後に統合テストを実行することができます。

選択肢は...

  1. 別々のディレクトリに分割する。

  2. (v3から)Junit4に移行し、クラスを分離するためのアノテーションを付ける。

  3. クラスが何であるかを示すために、ファイルの命名規則を使用します。 AdapterAIntergrationTest のように。

3 は、Eclipse に "選択したプロジェクト/パッケージまたはフォルダー内のすべてのテストを実行する" というオプションがあるという問題があります。そのため、統合テストだけを実行することは非常に困難です。

2: 開発者がユニットテストクラスで統合テストを書き始めるかもしれないというリスクがあり、それは単に面倒になります。

1: 最もすっきりしたソリューションのように見えますが、私の直感では、もっと良いソリューションがあるに違いないと思います。

統合テストと適切な単体テストをどのように分けているのでしょうか?

どのように解決するのですか?

JUnitのカテゴリとMavenを使って非常に簡単に分割することができます。

これは、ユニットテストと統合テストを分割することによって、以下にとてもとても簡単に示されます。

マーカーインターフェースの定義

カテゴリを使用してテストをグループ化する最初のステップは、マーカーインターフェイスを作成することです。

このインターフェイスは、統合テストとして実行させたいすべてのテストに印をつけるために使用されます。

public interface IntegrationTest {}

テストクラスをマークする

カテゴリアノテーションをテストクラスの先頭に追加します。 これは新しいインターフェースの名前を取ります。

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Mavenのユニットテストを設定する

このソリューションの優れた点は、ユニットテスト側には何も変更がないことです。

我々は、統合テストを無視するように、maven surefireプラグインにいくつかの設定を追加するだけです。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

mvn clean test を実行すると、マークされていないユニットテストだけが実行されます。

Mavenの統合テストを設定する

これも設定は非常にシンプルです。

統合テストだけを実行するには、これを使用します。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

これをプロファイルで囲むと、idが IT を使うと、高速なテストだけを実行することができます。 mvn clean install . 統合テストと低速テストのみを実行するには、以下のようにします。 mvn clean install -P IT .

しかし、ほとんどの場合、デフォルトで高速なテストを実行したいでしょうし、また すべて のテストを -P IT . もしそうなら、トリックを使う必要があります。

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

見ての通り、私はこのようなアノテーションを持つテストを除外しています。 java.io.Serializable . これはプロファイルが Surefire プラグインのデフォルト設定を継承するために必要なことで、たとえ <excludedGroups/> または <excludedGroups></excludedGroups> の場合、値 com.test.annotation.type.IntegrationTest が使用されます。

また none を使用することもできません(Mavenがこれをチェックします)。

注意事項

  • への依存は surefire-junit47 への依存は、Maven が JUnit 4 ランナーに自動的に切り替わらない場合にのみ必要です。を使用すると groups または excludedGroups 要素がスイッチのトリガーとなるはずです。 こちらをご覧ください .
  • 上記のコードのほとんどは、Maven Failsafe プラグインのドキュメントから引用したものです。JUnitのカテゴリを使用する」セクションを参照してください。 このページの .
  • テスト中に、私はこれが @RunWith() アノテーションを使用してスイートまたは Spring ベースのテストを実行する場合にも有効であることがわかりました。