はじめに
テストを書く際に避けて通れない JUnit。
しかし、現在は JUnit4 と JUnit5 (Jupiter) が併存しており、
「どちらを使うべきか?」で迷う方も多いのではないでしょうか。
この記事では JUnit4 と JUnit5 の違いを整理 し、
さらに Kotlin/Coroutines プロジェクトでの実務上のポイントも解説します。
1. 基本情報
| 項目 | JUnit4 | JUnit5 (Jupiter) |
|---|---|---|
| 座標 (Gradle/Maven) | junit:junit:4.x |
org.junit.jupiter:junit-jupiter:5.x |
| 実行基盤 | 直接実行 | JUnit Platform 上で Engine 方式 |
| リリース年 | 2006 | 2017 |
| 状態 | レガシー (保守のみ) | 現役・推奨 |
2. アノテーション比較
| JUnit4 | JUnit5 |
|---|---|
@Before / @After
|
@BeforeEach / @AfterEach
|
@BeforeClass / @AfterClass
|
@BeforeAll / @AfterAll(@TestInstance(PER_CLASS)でstatic不要) |
@Ignore |
@Disabled |
@Category |
@Tag |
@RunWith |
@ExtendWith |
3. API の違い
例外検証
JUnit4
@Test(expected = IllegalStateException.class)
public void test() { ... }
JUnit5
@Test
fun test() {
val e = assertThrows<IllegalStateException> { doSomething() }
assertEquals("boom", e.message)
}
タイムアウト
JUnit4
@Test(timeout = 1000)
public void test() { ... }
JUnit5
@Test
fun test() {
assertTimeout(Duration.ofMillis(1000)) {
doWork()
}
}
パラメータ化テスト
JUnit5
@ParameterizedTest
@CsvSource("2,4", "3,9")
fun sqr(x: Int, expected: Int) {
assertEquals(expected, x * x)
}
4. Gradle 設定例
JUnit5(推奨)
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
}
tasks.test {
useJUnitPlatform()
}
JUnit4
dependencies {
testImplementation("junit:junit:4.13.2")
}
共存 (Vintage Engine)
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.10.2")
}
tasks.test {
useJUnitPlatform()
}
5. 移行の流れ(JUnit4 → JUnit5)
-
useJUnitPlatform()を有効化し、Jupiter を導入 - 既存資産が多い場合は Vintage Engine で共存
- アノテーションを置換
-
@Before→@BeforeEach -
@Ignore→@Disabled
-
-
expected/timeoutをassertThrows/assertTimeoutに変更 -
Runner/Ruleを Extension へ移行
まとめ
- 新規プロジェクトは JUnit5 一択
- JUnit4 は Vintage Engine で「動かしながら移行」可能
- Kotlin/Coroutines テストは JUnit5 + kotlinx-coroutines-test がベストプラクティス