Webエンジニア

【Kotlin】KotestのFreeSpecで「No tests found for given includes: [XXXXX](–tests filter)」とエラーが出る場合の原因

KotestをFreeSpecで書いていて「No tests found for given includes: [XXXXX](–tests filter)」という謎のエラーが発生し原因が分からず悩んだ事があったのでメモ。

原因はFreeSpecの書き方でした。

スポンサーリンク

環境

  • IntelliJ IDEA 2022.1.3 (Community Edition)
  • Kotest(intellij IDEA Plugin) 1.2.60-IC-2022.1
  • kotlin 1.6.21
  • kotest 4.6.0

IntelliJ IDEAの設定

[IntelliJ] JUnit4 + Gradle – update broke all tests with error: no tests found for given includes
https://linked2ev.github.io/devsub/2019/09/30/Intellij-junit4-gradle-issue/

こんな記事を見てIntellij IDEAの設定をまず見直しました。

FreeSpecの書き方が原因

FreeSpecはネストの階層をユーザ好みで書けることがメリットです。

OKバージョン

class MyTests : FreeSpec({
    "文字列のテスト" - {
        "ねこのlengthは2であること" {
            "ねこ".length shouldBe 2
        }
    }
})

NGバージョン

こちらがNGバージョンになります。これで実行すると「No tests found for given includes ~」 となりました。

class MyTests : FreeSpec({
    "文字列のテスト" - {
        "ねこのlengthは2であること" - { // 一番内側のブロックに最後に - を付けるとエラーになる
            "ねこ".length shouldBe 2
        }
    }
})

これは公式ドキュメントにも書いてありますが、FreeSpecのルールだそうです。

一番内側のブロックには – を使わない とのこと。

The innermost test must not use the - (minus) keyword after the test name.

https://kotest.io/docs/framework/testing-styles.html#free-spec

大量にテストケースが並んでると見落としやすい

FreeSpecの一番のメリットはユーザが好きにテストコードの構造をいくらでもネスト出来ることです。

ただ、その使いやすさと裏腹に一瞬見落としやすい作りになっています。

class MyTests : FreeSpec({
    "文字列のテスト" - {
        "ねこのlengthは2であること" {
            "ねこ".length shouldBe 2
        }
    }

    "文字列のテスト2" - {
        "ねこ2に関して" - {
            "ねこのlengthは3であること" - { // ここだけ記述ミス。だが気付きにくい。
                "ねこ3".length shouldBe 3
            }
        }
    }
    "文字列のテスト3" - {
        "ねこ3のlengthは3であること" {
            "ねこ3".length shouldBe 3
        }
    }
})

番外編

他にもうっかりミスしてしまうFreeSpecの書き方。

一瞬戸惑うOKパターン

ちなみにこれだと何故かテスト自体は検知されます。

どうやらハイフンなしのブロック内のブロックは無視される模様。

"文字列のテスト2" - {
    "ねこ2に関して" {
        "ねこ2のlengthは3であること" - {
            "ねこ3".length shouldBe 3
        }
    }
}

試しにテストケースを失敗させるとこういう結果になります。テストケース名は結果に表示されません。

コンパイル出来ないNGパターン

これはエラーが出ます。ハイフン付きのブロック内にハイフン付きのブロックです。
「Using ‘invoke(suspend TestContext.() -> Unit): Unit’ is an error. Cannot nest lead test inside another leaf test ‘」

"文字列のテスト2" - {
    "ねこ2に関して" {
        "ねこのlengthは3であること" {
            "ねこ3".length shouldBe 3
        }
    }
}

 

FreeSpec ではなく、DescribeSpec とかを使っていきたい

ということでネストの自由さがウリのFreeSpecだが、実際に書くときは構造を瞬時に理解できる別のSpecと使いたい。

例えばDescribeSpec とかだとこんな風に書ける。不要なミスがなくなる。

class MyTests : DescribeSpec({
    describe("ねこのテスト") {
        it("ねこのlengthは3であること") {
            "ねこ3".length shouldBe 3
        }
        describe("ねずみのlength") {
            it("ねずみのlengthは3であること") {
                "ねこ3".length shouldBe 3
            }
            it("ねずみ2のlengthは4であること") {
                "ねこ3".length shouldBe 3
            }
        }
    }
})

 

おしまい

コメント

タイトルとURLをコピーしました