概要
Mavenでテストを実行すると、通常はプロジェクト内のすべてのテストが対象になる。
修正したクラスのテストだけを確認したい場合、maven-surefire-pluginの -Dtest オプションで実行対象を絞り込める。
バージョン
- Maven 3.9
- maven-surefire-plugin 3.5.2
- JUnit 5.11.4
- JUnit 4.13.2
テストクラスを1つだけ実行する
-Dtest にテストクラス名を指定する。クラス名は拡張子 .java を付けずに指定する。
$ mvn test -Dtest=CircleTest
パッケージまで含めた完全修飾クラス名も指定できる。同名のテストクラスが複数存在する場合に使う。
$ mvn test -Dtest=com.example.CircleTest
-Dtest はpom.xmlに設定した <includes> と <excludes> を上書きする。<excludes> で除外したテストクラスも -Dtest で明示すれば実行される。
テストメソッドを1つだけ実行する
クラス名とメソッド名を # で区切る。
$ mvn test -Dtest=CircleTest#testArea
+ でつなぐと複数のメソッドを指定できる。
$ mvn test -Dtest=CircleTest#testArea+testCircumference
パターンで絞り込む
シェルによるクォート
パターンで使う * や ! はシェルが解釈する文字である。zshでは -Dtest=*Test がファイル名展開の対象となり no matches found で失敗する。
-Dtest=... 全体をシングルクォートで囲むと、シェルによらず意図したパターンをMavenに渡せる。
$ mvn test '-Dtest=CircleTest#test*'
ワイルドカード
* は0文字以上、? は1文字にマッチする。クラス名とメソッド名のどちらでも使える。
$ mvn test '-Dtest=Circle*'
$ mvn test '-Dtest=CircleTest#test*'
$ mvn test '-Dtest=*Test#testArea'
複数指定
カンマ区切りで複数のクラスやパターンを並べられる。
$ mvn test -Dtest=CircleTest,SquareTest
除外
先頭に ! を付けると除外指定になる。以下は CircleTest 以外のテストを実行する。
$ mvn test '-Dtest=!CircleTest'
正規表現
%regex[...] で正規表現を指定できる。正規表現は完全修飾クラス名に対して評価するため、末尾の .class まで含めて書く。
$ mvn test '-Dtest=%regex[.*.Circle.*Test.class]'
パス
スラッシュ区切りのパスパターンも指定できる。** は任意の階層にマッチする。特定パッケージ配下のテストのみを実行する場合に使う。
$ mvn test '-Dtest=com/example/**/*Test.java'
パラメータ化テストの扱い
JUnit 5の @ParameterizedTest では、メソッド名を指定すると全パラメータ分が実行される。個々の実行のみを選ぶ指定はできない。
$ mvn test -Dtest=CircleTest#testRadius
>>> CircleTest#testRadius radius=1
>>> CircleTest#testRadius radius=2
>>> CircleTest#testRadius radius=3
JUnit 4の @RunWith(Parameterized.class) の場合は、メソッド名のあとに角括弧で0始まりのインデックスを指定して1回分だけ実行できる。
$ mvn test '-Dtest=ParamTest#testValue[1]'
>>> ParamTest#testValue value=2
[*] を指定すると全パラメータ分が対象になる。
テストが見つからない場合
指定したパターンに一致するテストが存在しないと、Surefireはエラーでビルドを失敗させる。
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.2:test (default-test) on project demo: No tests matching pattern "NoSuchTest" were executed! (Set -Dsurefire.failIfNoSpecifiedTests=false to ignore this error.)
エラーを無視する場合は -Dsurefire.failIfNoSpecifiedTests=false を指定する。
$ mvn test -Dtest=NoSuchTest -Dsurefire.failIfNoSpecifiedTests=false
似た名前の -DfailIfNoTests はテストが1件も存在しない場合にビルドを失敗させるかの設定で、デフォルトは false である。
-DfailIfNoTests=false はデフォルト値の指定にすぎず、パターン不一致のエラーは抑止できない。
マルチモジュールプロジェクトの場合
マルチモジュール構成でルートから -Dtest を指定すると、対象のテストを持たないモジュールでパターン不一致のエラーが発生する。
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.2:test (default-test) on project mod-b: No tests matching pattern "ModATest" were executed!
-pl でモジュールを絞り込むと、対象モジュールのみをビルドするためエラーを回避できる。実行時間も短くなる。
$ mvn test -pl mod-a -Dtest=ModATest
対象モジュールが同じプロジェクト内の他モジュールに依存する場合、-pl だけでは依存解決に失敗する。-am を併用して依存モジュールもビルド対象に含める。
$ mvn test -pl mod-b -am -Dtest=ModBTest -Dsurefire.failIfNoSpecifiedTests=false
全モジュールを対象としたままにする場合は -Dsurefire.failIfNoSpecifiedTests=false を併用する。
$ mvn test -Dtest=ModATest -Dsurefire.failIfNoSpecifiedTests=false
コンパイルを省略して実行する
mvn test はテスト実行前にコンパイルまでのフェーズを実行する。
コードを変更しておらず、直前のビルド結果をそのまま使う場合は surefire:test ゴールを直接呼び出すとコンパイルを省略できる。
$ mvn surefire:test -Dtest=SquareTest
ただし surefire:test はコンパイルを実行しないため、target/test-classes が古いままだと変更前のコードでテストが動く。コードを変更した場合は mvn test を使う。
結合テストの場合
maven-failsafe-pluginで実行する結合テストは -Dtest の対象外である。-Dit.test に同じ記法で指定する。
$ mvn verify -Dit.test=CircleIT
参考
- Running a Single Test – Maven Surefire Plugin
- Inclusions and Exclusions of Tests – Maven Surefire Plugin
- surefire:test – Maven Surefire Plugin
