本資料について
- 本資料は、第十六回 #渋谷java にて発表された資料です。
自己紹介
- 福原和朗 @kazurof
- Qiita, twitter, Facebook とかやってます。
- 所属
- GMOリサーチ
- アンケートシステムの開発保守
- GMOリサーチ
本日のお題
- JUnit 5.0.0-M1 が、2016/7/7にリリースされました
- 七夕さま
- 七夕さま
- いじってみた感触など並べてみます。
- 注意:Milestoneなので今後変更入るかもしれません。
そもそもの大前提
- 元となるパッケージ名が変わった。
org.junit.jupiter
-
org.junit.platform
など - JUnit4 とのAPI互換性はありません。
- Java8以降をサポート。
- Java7以前はさようなら。
JUnit5 のサブモジュール
- JUnit Platform
- テストの実行の全体枠組み
- JUnit Jupiter
- テスト開発者・拡張の開発者向けAPI
- JUnit Vintage
- JUnit3, 4 の実行API
Jupiter という名前の由来
- 太陽系の5番目の惑星からとったそうです。
- "Jupiter is the fifth planet from the sun."
- 参考
JUnit5で何が変わったか?
- 基本的なやり方は変わっていない。
@Test
テストメソッド
@BeforeEach
事前処理
@AfterEach
事後処理
サンプル
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class FirstJUnit5Tests {
@Test
void myFirstTest() {
assertEquals(2, 1 + 1);
}
}
無くなった(?)もの
- assertThat
アサーション系の機能は好きなもの使ってね、というスタンスらしい。
無くなった(?)もの
- TestSuite
- 複数のテストを木構造のようにグループ化
- テストメソッドに"タグ"をつけるやり方に移行
@Tag("nantoka")
- 従前、
Categories
と呼ばれていた機能。- 以前はexperimentalだった。
JUnit4 のTestSuite
//こんなボイラープレートコードは大変かも!
package tryjunit4.suite;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( { SampleTest.class, AnotherTest.class,
tryjunit4.subpack.AllTests.class })
public class AllTests {
}
JUnit5 の@Tag
の例
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
//"fast"タグを指定してテスト実行などできる
@Tag("fast")
class TaggingDemo {
@Test
@Tag("taxes")
void testingTaxCalculation() {
}
}
無くなった(?)もの
-
@Rule
による拡張- なくなる見込み。多分。
- そもそも、フィールドを使う形なので大仰になりがちだった。
- 新たに設計された拡張が導入される。
@ExtendWith
import org.junit.rules.TestName;
public class TestNameTest {
//Ruleはフィールドを使うので
//別のテストで使ってないか注意必要
@Rule
public TestName name = new TestName();
@Test
public void testA() {
assertEquals("testA", name.getMethodName());
}
@Test
public void testB() {
assertEquals("testB", name.getMethodName());
}
}
TestName
はどうなった?
- テスト名をとれる
@Rule
のAPI - 消えます。
- 代わりに、テストメソッドのパラメータから取れます。
- テスト名含む各種情報も取れます。
TestInfo
テストにパラメータを渡せる
- どんなパラメータを渡すかもカスタマイズ可能
-
ParameterResolver
によるしくみ
-
- 組み込みのResolver
TestInfoParameterResolver
-
TestReporterParameterResolver
- テストでログを吐きたい時の委譲先
import org.junit.jupiter.api.TestInfo;
// importは適当に省略してます。
class TestInfoDemo {
@Test
@Tag("my tag")
void test1(TestInfo testInfo) {
assertTrue(testInfo.getTags().contains("my tag"));
}
@Test
void test2() { }
}
できるようになったこと
- テスト名を個別につけられるようになった。
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
class DisplayNameDemo {
@Test
@DisplayName("なんとかてすと")
void testWithDisplayNameContainingSpaces() {
}
}
できるようになったこと
- テストクラスを内部クラスとする機能が標準になりました。
- experimental ではなくなりました。
@Nested
できるようになったこと
-
DynamicTest
- テストを作る処理を書くことができる。
- 動的にテストが作られる。
- テストを作る処理を書くことができる。
parameterized
の代替
テスト対象メソッドに、テストデータを多数渡してテストしたい。
- テストしたい処理
- テストデータを作る処理
以上をラムダで書いておくと、JUnit5が組み合わせて実行してくれます。動的です。
// JUnit4 だとやっぱりフィールドを使うので、つかいにくい
@RunWith(Parameterized.class)
public class NoConstructorTest {
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] { { 1, 1 }, { -2, 2 } });
}
@Parameter
public int fInput;
@Parameter(1)
public int fExpected;
@Test
public void testNantoka() {
assertEquals(fExpected, Math.abs(fInput));
}
}
JUnit5 M1 の個人的な感想
- 普通の機能はそのまま。
- experimentalで便利な機能を標準機能に昇格させる。
- テストメソッドだけで機能が完結するような設計にする。
-
Rule
の廃止。ExtendWith
による新設計
-
興味を持ったら。
-
https://github.com/junit-team/junit5-samples
- サンプルプロジェクト
- gradleのJUnit5プラグインとか試せます。
- コードに絵文字が普通に入っているので環境によっては修正必要かも
IDE
- IntelliJ IDEA 2016.2 がおすすめ。
- テストクラス右クリックからテスト実行できます。
- テストメソッドだと実行はできるが謎のエラーが出る。
JUnit4なプロジェクトの場合
-
@RunWith(JUnitPlatform.class)
で、ツール側にはJUnit4のテストだとみせかけつつ、中身はJUnit5のテストを実行するとができる。
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
@RunWith(JUnitPlatform.class)
public class JUnit4ClassDemo {
@Test
void succeedingTest() {
}
@Test
void failingTest() {
fail("Failing for failing's sake.");
}
}
今回触れてないこと
- 例外を想定するテスト
- 簡潔に書けるようになりました。
-
ExpectedException
というRuleは消えます。
- Interface の
default
メソッドのテスト - 他にも色々あるとおもいます。多分。
参考文献
- http://junit.org/junit5/docs/5.0.0-M1/user-guide/
- http://blog.codefx.org/libraries/junit-5-dynamic-tests/