CLOVER🍀

That was when it all began.

Mavenで「mvn test」とオプションのメモ

Mavenを使っていて、よく忘れるので個人的なメモを兼ねて。

当方、このブログを書く時はだいたいCLIで、IDEとか使わない(重い)のでこのあたりを使おうとしてよく忘れているというか…ハイ。

テストを実行する

なんのことはなく、普通に。

$ mvn test

テストをスキップする

実行したいコマンドと一緒に、「-Dmaven.test.skip=true」を付与。

$ mvn package -Dmaven.test.skip=true


Maven Surefire Plugin – Skipping Tests

テストの実行はスキップするが、テストコードのコンパイルは行う

「-Dmaven.test.skip=true」だとテストコードのコンパイルも含めてスキップされますが、テストは飛ばしたいけれどもテストコードのコンパイルはしたい場合は「-DskipTests=true」を付与します。

$ mvn package -DskipTests=true

Maven Surefire Plugin – Skipping Tests

テスト対象のクラスを指定する

スケープゴート的に、こんなクラスを用意。
src/test/java/Sample1Test.java

import static org.assertj.core.api.Assertions.*;

import org.junit.Test;

public class Sample1Test {
    @Test
    public void test1() {
        String str = "Hello World";
        assertThat(str)
            .isEqualTo("Hello World");
    }

    @Test
    public void test2() {
        int result = 1 + 2;

        assertThat(result)
            .isEqualTo(3);
    }
}

その他…
src/test/java/Sample2Test.java

import static org.assertj.core.api.Assertions.*;

import org.junit.Test;

public class Sample2Test {
    // Sample1Testと中身一緒
}

こんなのも。

src/test/java/ATest.java
src/test/java/A1Test.java
src/test/java/BTest.java

全部中身一緒。まあ、ひどい。

テスト対象を絞り込むには、「-Dtest=XXXX」で指定します。

Maven Surefire Plugin – Running a Single Test

いくつかサンプルを。

$ mvn test -Dtest=Sample*Test

結果。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running Sample2Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.264 sec
Running Sample1Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.012 sec

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

「,」区切りで複数指定。

$ mvn test -Dtest=Sample*Test,A*Test

結果。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running Sample2Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.26 sec
Running A1Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec
Running ATest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec
Running Sample1Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.047 sec

Results :

Tests run: 8, Failures: 0, Errors: 0, Skipped: 0

単品でも。

$ mvn test -Dtest=BTest

結果。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running BTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.584 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

テスト対象のメソッドを指定する

maven-surefire-pluginのバージョンが2.7.3以上であれば、メソッドまで絞れるらしいです。「#メソッド名」で指定します。

Maven Surefire Plugin – Running a Single Test

あ、テストコードは先ほどの例のものをそのまま利用します。

例。

$ mvn test -Dtest=ATest#test1

結果。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running ATest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.286 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

ちゃんと絞れています。

「*」との組み合わせも可能。

$ mvn test -Dtest=A*Test#test1

結果。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running A1Test
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.24 sec
Running ATest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.003 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

メソッド名にも「*」使えます。

$ mvn test -Dtest=A*Test#test*

結果。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running A1Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.357 sec
Running ATest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.039 sec

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

ただ、ここで「,」区切りにしたりするとコケました。少なくとも、maven-surefire-plugin 2.12.4では。

$ mvn test -Dtest=A*Test#test*,BTest

テストが失敗したことになるという…。

Results :

Tests in error: 
  BTest
  A1Test: String index out of range: -1
  ATest: String index out of range: -1

Tests run: 3, Failures: 0, Errors: 3, Skipped: 0

まあ、困らないとは思いますが。

除外については

ドキュメントを見る限り、「!」を付与すると除外パターンとして扱ってくれそうな雰囲気なのですが、実際試してみると(例えば「$ mvn test '-Dtest=!ATest'」)全テストがスルーされました…。何か間違ってるんでしょうかねぇ。

「テストがないよ」とエラーになる時には

こういうエラーが出力される時。

No tests were executed!  (Set -DfailIfNoTests=false to ignore this error.) -> [Help 1]

「mvn test」とかでテストはしたいものの、関連するモジュールとかにテストがなかったりするとコケてしまいます。
こういう時は「-DfailIfNoTests=false」を指定します。

$ mvn test -DfailIfNoTests=false

surefire:test / failIfNoTests

テストが失敗しても、ビルドが途中で中断して欲しくない時は

テストが大量にあるなどの理由でテストが失敗してもビルドが途中で中断して欲しくない場合は、
「-Dmaven.test.failure.ignore=true」を指定します。

$ mvn test -Dmaven.test.failure.ignore=true

surefire:test / testFailureIgnore

テストのプロセスにアタッチしたい/リモートデバッグしたい

テストに対してリモートデバッグするには、「-Dmaven.surefire.debug」を指定します。

$ mvn test -Dmaven.surefire.debug

これで実行するとアタッチ待ちで停止するので、IDEなどからリモートデバッグの設定を構成してデバッグしましょう。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Listening for transport dt_socket at address: 5005

明示的にオプションを指定する場合は、「-Dmaven.surefire.debug=」に続けて指定するとよいです。例えば、以下のように書くと
ローカルプロセスとしてアタッチできるようになります。

$ mvn test -Dmaven.surefire.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005

Maven Surefire Plugin – Debugging Tests

ちなみに、明示的に指定しなかった場合はなにが指定されているかというと、こんな感じ。
https://github.com/apache/maven-surefire/blob/surefire-2.21.0/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java#L2187-L2196
https://github.com/apache/maven-surefire/blob/surefire-2.19.1/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java#L1936-L1945

    private String getEffectiveDebugForkedProcess()
    {
        String debugForkedProcess = getDebugForkedProcess();
        if ( "true".equals( debugForkedProcess ) )
        {
            return "-Xdebug -Xnoagent -Djava.compiler=NONE"
                + " -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
        }
        return debugForkedProcess;
    }

その他

失敗時のスタックトレースが出力されない場合は、「-Dsurefire.useFile=false」を付与するといいですよーと。

surefire:test / useFile

参考)
surefire:test(のtestパラメータ)
http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#test
surefire:test(のskipTestsパラメータ)
http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#skipTests
Maven2のTipsを集めるWiki - CookBook
http://wiki.fdiary.net/maven2/?CookBook
Skip just some test in Maven
http://stackoverflow.com/questions/22658190/skip-just-some-test-in-maven