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
}
}
}
})
おしまい


コメント