私は大量の Junit テストを継承しましたが、これらのテストは (ほとんどが動作していないことを除けば) 実際の単体テストと統合テスト (外部システム、DB などが必要) が混在しています。
そこで、実際にそれらを分離して、単体テストを迅速かつ効率的に実行し、その後に統合テストを実行する方法を考えようとしています。
オプションは次のとおりです。
別々のディレクトリに分割します。
Junit4 (v3 から) に移行し、クラスに注釈を付けて分離します。
クラスが何であるかを判別するには、ファイル命名規則を使用します (例: AdapterATest および AdapterAIntergrationTest)。
3 には、Eclipse に「選択したプロジェクト/パッケージまたはフォルダー内のすべてのテストを実行する」オプションがあるという問題があります。そのため、統合テストを実行するのは非常に困難になります。
2: 開発者がユニット テスト クラスで統合テストを書き始め、混乱が生じるリスクがあります。
1: 最も優れた解決策のように思えますが、私の直感では、もっと良い解決策がどこかにあるはずです。
それで、私の質問は、統合テストと適切な単体テストをどのように分割するのでしょうか?
ベストアンサー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 ベースのテストを実行する場合でもこれが機能することがわかりました。