概要

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

参考