Kotest手がかり(Clues)

Kotestでは手がかり(Clues)を使用すると、Assertionに対して詳細な説明を提供できる。

手がかり

経験則として、失敗したテストは良いバグ報告のように見えるべきである。つまり、何が間違っているのか、理想的にはなぜ間違っているのかを知らせるべきである。

失敗したアサーションのエラーメッセージに、何が間違っているのかを知るための十分な情報が含まれている場合もある。

例:

username shouldBe "devkuma"

次のようなエラーが発生することがある。

expected:<"devkuma"> but was:<"devkuma@devkuma.com">

これが失敗すると、単に次のように得られることがある。

<null> should not equal <null>

これはあまり役立たない。ここでwithClueを活用できる。

withClueおよびasClueヘルパーは、アサーションに追加コンテキストを加え、失敗が自ら説明できるようにする。

たとえば、文字列メッセージとともにwithClueを使用できる。

withClue("Name should be present") {
    user.name shouldNotBe null
}

次のようなエラーが発生する。

Name should be present
<null> should not equal <null>

エラーメッセージはかなり改善されたが、まだ完璧ではない。たとえば、データベースを確認するにはユーザーIDが分かると役立つ場合がある。

asClueを使用して、エラーメッセージにユーザーIDを追加できる。

withClue({ "Name should be present (user_id=${user.id})" }) {
    user.name shouldNotBe null
}

また、asClue拡張関数を使用して、任意のオブジェクトを手がかりメッセージに変換することもできる。

{ "Name should be present (user_id=${user.id})" }.asClue {
    user.name shouldNotBe null
}

このメッセージはテストが失敗した場合にのみ生成されるため、コストの高い処理と一緒に使用しても安全である。

ドメインオブジェクトを手がかりとして使用することもできる。

data class HttpResponse(val status: Int, val body: String)

val response = HttpResponse(404, "the content")

response.asClue {
    it.status shouldBe 200
    it.body shouldBe "the content"
}

次のように出力される。

HttpResponse(status=404, body=the content)
Expected :200
Actual   :404

ネストされた手がかり

手がかりはネストでき、失敗したアサーションメッセージですべて確認できる。

{ "Verifying user_id=${user.name}" }.asClue {
  "email_confirmed should be false since we've just created the user".asClue {
    user.emailConfirmed shouldBe false
  }
  "login".asClue {
    user.login shouldBe "sksamuel"
  }
}

失敗は次のように表示されることがある。

Verifying user_id=42
email_confirmed should be false since we've just created the user
<true> should equal <false>

参照