AndroidStudioでJUnit5のテスト(ParameterizedTest)を実行する

いきなりまとめ

2024年1月現在も、AndroidStudioでJUnit5を用いてテストを実行するには3rdParty製のプラグイン導入が必要のようです。

github.com

AndroidStudioの公式サイトでも、テストを作成する際は

[Create Test] ダイアログで [JUnit4] を選択し

とあり、3rdParty製プラグインなしではJUnit5を使えなさそうなのです。
引用元↓
developer.android.com

この記事で書いていること

  • AndroidStudioでJUnit5を用いてテストを実行する方法
  • ParameterizedTestの記述例

参考サイト

JUnit5の導入方法については以下のサイトを参考にしております。

qiita.com

swet.dena.com

ParameterizedTestについては以下サイトを参考にしました。

sam09.github.io

hirabay.net

プラグイン・各記事作成の皆様に感謝です。

導入手順

前述参考サイトの1番目のQiita記事と重複しますが、プラグインのREADMEのSetup方法(下記リンク)に従えば大丈夫です。

GitHub - mannodermaus/android-junit5: Testing with JUnit 5 for Android.

自分の場合ParameterizedTestを書いたので、参考として以下まとめておこうと思います。

1. build.gradle.kts (Module:app) の先頭らへんに以下の感じで記載

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp")   // ←この辺の行は人によると思います
    id("de.mannodermaus.android-junit5") version "1.10.0.0"    // ←この行を追加です。バージョンはその時の最新のものを。
}

一応補足ですが、READMEに

declare the plugin in your app module's build script

ってあるので、モジュール用のbuild.gradleの方に記載します。

2. build.gradle.kts (Module:app) のdependenciesの中に以下の感じで記載

dependencies {

    // (略)
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")     // 必須
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0")   // 必須
    testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0")   // Parameterized Testsをやりたい場合に必須

3. Gradleファイルの再読み込み実施

build.gradleを書き換えると、AndroidStudioの上の方に Gradle files have changed うんたらのメッセージが出てくると思うので、Sync をクリックすれば大丈夫です。

ParamterizedTestの記述

1. テストのファイルを用意する

テスト対象のメソッドを右クリックし、Generate... を選択して Testを選択後、特にいじらずOKってやれば大丈夫です。
自分の場合、以下のスクリーンショットのようにJUnit5 library not found in the module ってメッセージが出ているのですが、前述の導入2で設定はしているので「Fix」は押さずにやっています。

テスト作成のウィンドウ

2. ParameterizedTestを書いてみる

ParameterizedTestというのは、「このメソッド、いろんなパターン(引数と期待値)でばーっとテストしておいて〜」という感じのテストです。パターンごとにテスト関数をせっせとコピペしつつちょっとパラメータを変えて・・という作業が不要になってとても楽です。

さて記述していきたいと思います。

なお、前提条件として以下のメソッド(月末が何曜日かの序数を返却する関数)をテストするとします。

// X年Y月の最終日の曜日の序数を返す
un getOrdinalNumberOfDayOfWeekForLastDay(
    year: Int,
    month: Int,
): Int {
    val targetYearMonth = LocalDate.of(year, month, 1)
    return LocalDate.of(year, month, targetYearMonth.lengthOfMonth()).dayOfWeek.value
}

では、1で作成されたファイルにテストを記述していきます。

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments.arguments
import org.junit.jupiter.params.provider.MethodSource
import java.time.DayOfWeek
import java.time.LocalDate

class HogeKtTest {
    companion object {
        @JvmStatic
        fun provideGetOrdinalNumberOfDayOfWeekForLastDayParameters() = listOf(
            arguments(2024, 1, 1),
            arguments(2024, 2, 4),
            arguments(2024, 3, 7),
        )
    }

    @ParameterizedTest
    @MethodSource("provideGetOrdinalNumberOfDayOfWeekForLastDayParameters")
    fun getOrdinalNumberOfDayOfWeekForLastDayTest(year: Int, month: Int, expect: Int) {
        val actual = getOrdinalNumberOfDayOfWeekForLastDay(year, month)

        assertEquals(
            actual,
            expect,
            "${year}年${month}月の最終日は${DayOfWeek.of(actual)}(期待値=${DayOfWeek.of(expect)})"
        )
    }
}

3. 実行する

テスト対象のクラスの左側に表示されるアイコンから「Run 'xxxxTest'」をクリックすればOKです。
(自分の場合テストがメソッドのバグで失敗しているので、赤いアイコンがついています。)

実行しよう

テスト実行結果は以下のようになりました。
2024年1月31日は水曜日なので3が返却されるのが正しいのですが、テストのパラメータのうち期待値を月曜日として誤っていたことにより、テスト失敗が一件発生しています。

テスト実行結果

補足

ParameterizedTestではなく普通のテストを実行したい場合は、 package org.junit.jupiter.apiの@Test をつけてテストメソッドを書けば良いと思います。

おわり

以上です。