MPのご利用は計画的に

だいたい自分用のメモ

JUnit5のTagアノテーションは便利そう だけど…

概要

JUnit5には@Tagというアノテーションがあって、テストをグルーピングして実行できると知った時のメモです。

環境

  • Kotlin 1.2.51
  • JUnit 5.2.0

JUnit4にもグルーピングはあった

JUnit4では@Categoryだったものが@Tagに変わったようですね。

https://junit.org/junit5/docs/current/user-guide/#migrating-from-junit4-tips

@Category no longer exists; use @Tag instead.

準備

KotlinとJUnit5の構成 をベースにして追記していきます。

準備ができたら

動かすテストクラスを作ります。今回は3つ用意してみました。
develop productionがそれぞれ指定されたクラスと、その両方が指定されたクラスです。

import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test

class DevelopTest {
    @Test
    @Tag("develop")
    fun develop() {
        Assertions.assertTrue(true, "Executed Develop test.")
    }
}
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test

class ProductionTest {
    @Test
    @Tag("production")
    fun production() {
        Assertions.assertTrue(true, "Executed production test.")
    }
}
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Tags
import org.junit.jupiter.api.Test

class AlwaysTest {
    @Test
    @Tags(Tag("develop"), Tag("production"))
    fun always() {
        Assertions.assertTrue(true, "Executed always.")
    }
}

@Tagsアノテーションを使うと複数の@Tagをまとめられます。

クラスができたら

pom.xmlに設定を追加します。
maven-surefire-pluginconfigurationに追加です。
ここではアノテーションdevelopを指定しているテストのみ動かす設定です。

<build>
...
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.0</version>
            <configuration>
                <properties>
                    <includeTags>develop</includeTags>
                </properties>
            </configuration>
        </plugin>
    </plugins>
...
</build>

ここで問題が

Referenceにある通り includeTags を指定するも、なぜかすべてのテストが動いてしまうという現象が発生。
なんでだろうと悩んで試しにタグを groups に変えると動きました…。

<properties>
    <groups>develop</groups>
</properties>

バグ…なのかな?

実行してみた

$ mvn test
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.panage.junit5.AlwaysTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.019 s - in com.example.panage.junit5.AlwaysTest
[INFO] Running com.example.panage.junit5.DevelopTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 s - in com.example.panage.junit5.DevelopTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.767 s
[INFO] Finished at: 2018-07-22T12:02:19+09:00
[INFO] ------------------------------------------------------------------------

ためしに設定を書き換えてみると

<properties>
    <groups>production</groups>
</properties>
$ mvn test
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.panage.junit5.AlwaysTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.019 s - in com.example.panage.junit5.AlwaysTest
[INFO] Running com.example.panage.junit5.ProductionTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 s - in com.example.panage.junit5.ProductionTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.767 s
[INFO] Finished at: 2018-07-22T12:02:19+09:00
[INFO] ------------------------------------------------------------------------

うまく切り替わるようになりました。

設定を毎回書き換えるのは面倒です

ということで、こちらを参考にprofileを作って、実行時のprofileに応じて変わるようにしました。

stackoverflow.com

<profiles>
    <profile>
        <id>develop</id>
        <properties>
            <include.tags>develop</include.tags>
        </properties>
    </profile>
    <profile>
        <id>production</id>
        <properties>
            <include.tags>production</include.tags>
        </properties>
    </profile>
</profiles>
...

<build>
...
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.0</version>
            <configuration>
                <properties>
                    <groups>${include.tags}</groups>
                </properties>
            </configuration>
        </plugin>
    </plugins>
...
</build>
# developの場合
$ mvn -P develop test

# productionの場合
$ mvn -P production test

雑感

うまく使えば便利そうだなと思う半面、使いすぎると収拾つかなくなってカオスになりそうにも感じます。
「Production」「Develop」「外部通信が必要」程度にしておくのが良いかもしれないという気持ちです。