🐦

Kotlinでテストを書いた話2 データ駆動型編 (kotest-framework-datatest)

2021/08/18に公開

概要

前回の記事に続き、kotestのお話をします。
今回はデータ駆動型テストを書いてみたいと思います。
1テストスクリプトで、様々なデータパターンでテストを行うのが容易になります。

実行環境

  • Windows 10
  • IntelliJ IDEA 2021.2
  • kotlin 1.4.21
  • ktor 1.5.1
  • kotest 4.6.1
    • kotest-framework-datatest 4.6.1

準備

  1. 依存関係を追加
    build.gradle.kts
    dependencies {
        testImplementation("io.kotest:kotest-framework-datatest:4.6.1")
    }
    

テスト内容

  • 掛け算のパターンテストすることにします。

    1. 正 (25=10)
    2. 0 (50=0)
    3. 負 (-2-3=6)
    4. 0 (-60=0)
    5. 負 (3-7=-21)
  • テストクラスを作成

    TimesClass.kt
    class TimesTest : FunSpec( {
        context("TimesTest"){
            TimesClass.calc(2, 5) shouldBe 10
            TimesClass.calc(5, 0) shouldBe 0
            TimesClass.calc(-2, -3) shouldBe 6
            TimesClass.calc(-6, 0) shouldBe 0
            TimesClass.calc(3, -7) shouldBe -21
        }
    })
    

まずは普通にテストを書く

  1. テストクラスを作成

    TimesTest.kt
    class TimesTest : FunSpec( {
        context("TimesClass"){
            test("calc"){
                TimesClass.calc(2, 5) shouldBe 10
                TimesClass.calc(5, 0) shouldBe 0
                TimesClass.calc(-2, -3) shouldBe 6
                TimesClass.calc(-6, 0) shouldBe 0
                TimesClass.calc(3, -7) shouldBe -21
            }
        }
    })
    
  2. テストを実行
    TimesTest

データテストを書く

  1. テスト用パラメータデータクラスを作成

    TestPalam.kt
    data class TestParam(val param1: Int, val param2: Int, val expected: Int)
    
  2. テストを書く

    TimesTest.kt
    class TimesTest : FunSpec( {
        context("TimesClass"){
            withData(
                TestParam(2, 5, 10),
                TestParam(5, 0, 0),
                TestParam(-2, -3, 6),
                TestParam(-6, 0, 0),
                TestParam(3, -7, -21),
            ) { 
                TimesClass.calc(it.param1, it.param2) shouldBe it.expected 
            }
        }
    })
    
  3. テストを実行
    テスト結果を見るだけで、データパターンを5つ繰り返していること明確になりました。
    これだけでも"可視性向上"や"変更容易性向上"が見込めそうです。
    (テストコードの効果の話を始めると長くなるので、割愛します)
    TimesTest

テスト結果をカスタマイズする

  1. テスト用パラメータデータクラスを修正

    TestPalam.kt
    - data class TestParam(val param1: Int, val param2: Int, val expected: Int)
    + data class TestParam(val param1: Int, val param2: Int, val expected: Int): WithDataTestName {
    +     override fun dataTestName() = "${param1}*${param2}=${expected}"
    + }
    
  2. テストを実行
    このひと手間だけでテスト結果の可視性がまた向上したのではないでしょうか。
    複雑になればなるほど、この手間の効果が出てくると思います。
    TimesTest

最後に

今回は以上になります。
次はMockkの話をしたいと考えてます。

Kotlinの普及を願って。
ことりんかわいい!

Discussion