mike-neckのブログ

Java or Groovy or Swift or Golang

JUnit5入門(1) - テストクラスの作成とテストの実行

年末にかけてJUnit5(junit-jupiter)をいじったのでまとめ。

使い方的な話はQiitaにある記事のほうが詳しいかもしれない…

qiita.com

qiita.com

qiita.com

qiita.com


JUnit5ライブラリーの導入

テストコンパイルスコープにjunit-jupiter-api、テストランタイムにjunit-jupiter-engineを用いるようにする。

build.gradle
repositories {
  mavenCentral()
  jcenter()
}

dependencies {
  testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-M3"
  testRuntime "org.junit.jupiter:junit-jupiter-engine:5.0.0-M3"
}
pom.xml
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <version>5.0.0-M3</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>5.0.0-M3</version>
  <scope>test</scope>
</dependency>

JUnit5のテストクラスとテストメソッドの作り方

JUnit4とほとんど変わらない。プレーンなクラスを作って、 @Test アノテーションをテストメソッドに付加するだけで実行してくれる。

サンプルコード
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

@Slf4j
public class SimpleTest {

    @Test
    void firstTest() {
        log.info("1st test");
    }
}

@Test アノテーションを付与するメソッドは、staticメソッドではなく、またprivateなメソッドでない必要がある。

実行結果
1 01, 2017 12:55:22 午後 org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines
情報: Discovered TestEngines with IDs: [junit-jupiter]
12:55:28.796 [INFO  com.example.ex1.SimpleTest] - 1st test

コードサンプル


JUnit5の実行方法

IDEからの実行

IntelliJ IDEA

デフォルトの状態でJUnit5を実行できるようになっている。なお、実行方法はこれまでと変わらない。

f:id:mike_neck:20170101154113p:plain

テストクラスの左側にある実行ボタンをクリックして、メニューから「Run クラス名 」を実行する。

f:id:mike_neck:20170101154237p:plain

f:id:mike_neck:20170101154313p:plain

Eclipse

知らない…ごめん…

Bug 488566 - [JUnit][JUnit 5] Add support for JUnit 5を読むかぎり、Eclipse 4.7 M4にてJunit5のサポートがあるようです。

Netbeans

知らないし、ググっても出てこないけど、console-launcherは単なるjavaアプリケーションなので必要なライブラリーをclasspathに指定しつつ、console-launcherを起動すれば実行できる。

Gradleからの実行

Gradleにjunit-platformプラグインを導入して、 junitPlatformTest タスクを実行するとテストを実行できる。

build.gradle
buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath "org.junit.platform:junit-platform-gradle-plugin:1.0.0-M3"
  }
}

apply plugin: 'java'
apply plugin: 'org.junit.platform.gradle.plugin'
実行結果

junitPlatformTest は長いので jPT で指定することもできる。

$ gradle jPT
:compileJava
:processResources
:classes
:compileTestJava
:processTestResources
:testClasses
:junitPlatformTest
12 31, 2016 9:39:27 午後 org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines
情報: Discovered TestEngines with IDs: [junit-jupiter]
21:39:33.471 [INFO  com.example.ex1.SimpleTest] - 1st test
Test run finished after 11642 ms
[          1 containers found      ]
[         0 containers skipped    ]
[         1 containers started    ]
[         0 containers aborted    ]
[         1 containers successful ]
[         0 containers failed     ]
[         1 tests found           ]
[         0 tests skipped         ]
[         1 tests started         ]
[         0 tests aborted         ]
[         1 tests successful      ]
[         0 tests failed          ]

BUILD SUCCESSFUL

Total time: 12.576 secs

注意点

GradleでJunit5を起動するときに注意したい所は次の点

  • Gradleのバージョンは2.5以上が必要
  • junit-platformjunit-jupiter とがややこしい
    • コンパイル時に必要なライブラリーのgroupが org.junit.jupiter で、gradleのプラグインのほうのgroupが org.junit.platform
    • junit-jupiter のバージョン(いわゆるJUnit5のバージョン)が 5.0.0.-M3junit-platform のバージョン(つまりgradleプラグインのバージョン)が 1.0.0-M3
  • 独自のJUnit5を走らせるタスクを作るのが非常に面倒くさい
    • junitPlatformTest タスクは単なる JavaExec タスクなので、同じようなものを作ろうとするとこれと同じようなコードを書かないといけない
      • まあ、そうではあるんだけど、gradleのissueにJunit5関連のissueが立っているので、gradleから公式のタスクが出るかもしれない
  • デフォルトでクラス名が Test あるいは Tests で終わるものだけをテストクラスとして読み取るようになっている(これとかこれなど)
    • そのため FooSpec というクラスに @Test を付与してもgradleからは起動できない
    • これを回避するためには次のように junitPlatform.filters.includeClassNamePattern あるいは junitPlatform.filters.includeClassNamePatterns に実行したいクラス名のパターンを指定する必要がある
junitPlatform {
  filters {
    includeClassNamePattern '^.*Spec$'
    // あるいは
    includeClassNamePatterns '^.*Spec$', '^.*Tests?$' 
  }
}