Android Spekでユニットテスト書いてみた

2017.12.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

まえがき

Kotlin Advent Calendar 2017 - Qiitaの14日目です。

ユニットテストを書く時に、もっといい感じに書きたいっと思う時があります。 そんなとき、Spek - A Kotlin Specification Framework for the JVMを発見しました。Androidで試してみました。

Androidでの導入は最後に書きます。

まずはSpekとJUnit4でのソースをみてみます。

Kotlin前提ですが、デフォルトはもうKotlinでいいよね?

比較

テスト対象

class SampleCalculator {
    fun sum(x: Int, y: Int): Int = x + y

    fun subtract(x: Int, y: Int): Int = x - y
}

Spekで書いてみる

@RunWith(JUnitPlatform::class)
object SampleCalculatorSpekTest : Spek({

    describe("SampleCalculatorのテスト") {
        val calculator = SampleCalculator()

        on("足し算") {
            val sum = calculator.sum(2, 4)

            it("2+4が6になるテスト") {
                assertEquals(6, sum)
            }
        }

        on("引き算") {
            val subtract = calculator.subtract(4, 2)

            it("4-2は2になるテスト") {
                assertEquals(2, subtract)
            }
        }
    }

})

JUnitで書いてみる

JUnit4で同じことをすると以下のようなソースになります。

@RunWith(Enclosed::class)
class SampleCalculatorTest {

    class 足し算 {
        lateinit var calculator: SampleCalculator
        @Before
        fun setup() {
            calculator = SampleCalculator()
        }
        @Test
        fun `2足す4が6になるテストになるテスト`() {
            assertEquals(6, calculator.sum(2, 4))
        }
    }

    class 引き算 {
        lateinit var calculator: SampleCalculator
        @Before
        fun setup() {
            calculator = SampleCalculator()
        }
        @Test
        fun `4引く2が2になるテストになるテスト`() {
            assertEquals(2, calculator.sum(4, 2))
        }
    }
}

まとめ

良い点

  • テストを日本語で書く場合、JUnitの場合は、エスケープしないといけない文字があり少し不便だったのが不要になった
  • classのネストで全体的に長かったのが短くなった
  • コンテキストを固定したテストがしやすくなった

悪い点

  • 設定仕方が悪いのか、Spekを使わないテストが動かなくなってしまった​

Android Spekの導入方法

app/build.gradleに以下を追加します。

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    testImplementation 'junit:junit:4.12'
    testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
    testImplementation "org.jetbrains.spek:spek-junit-platform-engine:1.1.5"
    testImplementation('org.jetbrains.spek:spek-api:1.1.5') {
        exclude group: 'org.jetbrains.kotlin'
    }
    testImplementation "org.junit.platform:junit-platform-runner:1.0.0"
}

Android StudioにSpekプラグインをインストールする

補足

もちろんAndroid Studioからではなくコマンド./gradlew testで実行できます。

※わざと失敗するようにテストケースを修正しました。

 ./gradlew test

> Task :app:testDebugUnitTest

com.kamedon.speksample.SampleCalculatorSpekTest > on 足し算.it 2+4が6になるテスト FAILED
    java.lang.AssertionError

2 tests completed, 1 failed


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:testDebugUnitTest'.
> There were failing tests. See the report at: file://...../SpekSample/app/build/reports/tests/testDebugUnitTest/index.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
19 actionable tasks: 1 executed, 18 up-to-date

結果がファイルにはき出されるので、見返しやすくてうれしいです。

参考文献