Kotest手がかり(Clues)
Kotestでは手がかり(Clues)を使用すると、Assertionに対して詳細な説明を提供できる。
手がかり
NOTE
手がかり(clues)は、Kotestアサーションライブラリを使用する場合にのみ動作する。
経験則として、失敗したテストは良いバグ報告のように見えるべきである。つまり、何が間違っているのか、理想的にはなぜ間違っているのかを知らせるべきである。
失敗したアサーションのエラーメッセージに、何が間違っているのかを知るための十分な情報が含まれている場合もある。
例:
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
}
このメッセージはテストが失敗した場合にのみ生成されるため、コストの高い処理と一緒に使用しても安全である。
TIP
テスト失敗には、失敗したアサーション、テスト名、手がかり、スタックトレースが含まれる。何が失敗し、なぜ失敗したのかを両方分かるように、この方法で使用することを推奨する。これにより、特にテスト作成者の意図をリバースエンジニアリングする場合に、テストを保守しやすくなる。
TIP
アサーションの上にコードコメントを書きたくなる場合は、代わりに`asClue`または`withClue`を使用することを推奨する。テスト失敗、特にCIでは手がかりが表示されるが、コメントは表示されない。
ドメインオブジェクトを手がかりとして使用することもできる。
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
NOTE
Kotestはすべての`() -> Any?`のような手がかりを遅延手がかりと見なし、それを計算して関数自体に`.toString()`を呼び出す代わりに、結果値に`.toString()`を使用する。ほとんどの場合、これは必要な処理を正確に行うが、手がかりオブジェクトが`() -> Any?`を実装しており、`clue.toString()`を使用したい場合は、手がかりを`{ clue.toString() }.asClue {... }`のように手動でラップすることを推奨する。
ネストされた手がかり
手がかりはネストでき、失敗したアサーションメッセージですべて確認できる。
{ "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>