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-plugin
のconfiguration
に追加です。
ここではアノテーションで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に応じて変わるようにしました。
<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」「外部通信が必要」程度にしておくのが良いかもしれないという気持ちです。
KotlinでJUnit5を使う
概要
KotlinとJUnit5を使うためのできるだけシンプルな構成を作ったときのメモです。
環境
まずはKotlinの準備
KotlinのReferenceに沿って設定すればOK。 今回はMavenを使っています。 https://kotlinlang.org/docs/reference/using-maven.html
Kotlinを使うために追加するのはこんな感じ。
<properties> <kotlin.version>1.2.51</kotlin.version> </properties> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> <build> <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> <plugins> <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile</id> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> <plugins> </build>
次はJUnit5の設定
ここにJUnit5を追加していきます。
こちらもReferenceに沿って依存を追加すれば大丈夫。
JUnit5を使うには最低限junit-jupiter-engine
を依存関係に含めることと、
Mavenから実行するにはmaven-surefire-plugin
が必要。
<properties> ... <junit.jupiter.version>5.2.0</junit.jupiter.version> ... </properties> <dependencies> ... <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>${junit.jupiter.version}</version> <scope>test</scope> </dependency> ... </dependencies> <build> ... <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.0</version> </plugin> </plugins> </build>
このブログの公開時にはmaven-surefire-plugin
のバージョンが2.21.0
を使うように書かれていますが、
2.22.0を使っても問題ないようです。
適当なクラスを作成
テストを実行するために適当なクラスを作ります。
今回はただhoge
という文字列を返すだけの関数を作りました。
package com.example.panage.junit5 class Hoge { fun say(): String = "hoge" }
テストクラスを作成
テストクラスを作成します。
テストを実行したい関数に@org.junit.jupiter.api.Test
アノテーションを付与すればOK。
package com.example.panage.junit5 import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test internal class HogeTest { @Test fun sayのテスト() { // setup val hoge = Hoge() // expect Assertions.assertEquals("hoge", hoge.say()) } }
hoge
という文字列が返ってくるはずなので、Assertions.assertEquals
で比較しています。
[INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.example.panage.junit5.HogeTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.013 s - in com.example.panage.junit5.HogeTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
雑感
KotlinもJUnitも公式のReferenceが整っているので、手順通りに進めれば問題ありませんでした。
テストクラスもいままでと同じように書けるので違和感もなさそうです。