TotT: メソッドの引数は、絞ってテストしよう。
こんにちは、kubopです。
Googleにはトイレテスト(TotT)という文化があるようで、テストに関するTipsをトイレに貼り出し、テストに関する知識を全社で共有しているらしいです。
昨今はリモート勤務が広まり、TotTの実施は難しく、SlackやBotを用いてもなかなか浸透するかどうか…
そこで、noteに書きつつ自分が勉強するために、少しずつ読んで内容や、所感を書いてみようと思います。
※ 翻訳・解釈の間違いなどあるかもしれません。
その場合はこっそり教えてください。
Testing on the Toilet: Only Verify Relevant Method Arguments
このテストは、脆く、壊れやすいです。何故でしょうか?
@Test public void displayGreeting_showSpecialGreetingOnNewYearsDay() {
fakeClock.setTime(NEW_YEARS_DAY);
fakeUser.setName("Fake User”);
userGreeter.displayGreeting();
// The test will fail if userGreeter.displayGreeting() didn’t call
// mockUserPrompter.updatePrompt() with these exact arguments.
verify(mockUserPrompter).updatePrompt(
"Hi Fake User! Happy New Year!", TitleBar.of("2018-01-01"), PromptStyle.NORMAL);
}
このテストでは、mockUserPrompterの全ての引数に正確な値を指定しています。これらの引数は、プロダクトコードが変更されたときに、たとえその変更がテスト対象の動作と無関係であった場合でも失敗します。
また、あまりに多くの引数を検証すると、どの引数がテストにとって重要で、どれが無関係なのかがわかりにくくなり、なんの動作をテストしているのかわかりにくくなります。
そのため、テストする対象に影響する引数のみを対象に検証するようにしましょう。(Mockitoのany()や、contains()など。
@Test public void displayGreeting_showSpecialGreetingOnNewYearsDay() {
fakeClock.setTime(NEW_YEARS_DAY);
userGreeter.displayGreeting();
verify(mockUserPrompter).updatePrompt(contains("Happy New Year!"), any(), any()));
}
このように検証する引数を限定すると、他のテストで検証することが可能です。このようなテストを行うと、一つのテストにつき、ひとつの動作しか検証しないことになり、より読みやすく、変更に強くなります。
@Test public void displayGreeting_renderUserName() {
fakeUser.setName(“Fake User”);
userGreeter.displayGreeting();
// Focus on the argument relevant to showing the user's name.
verify(mockUserPrompter).updatePrompt(contains("Hi Fake User!"), any(), any());
}
↑例えば、user nameに注目したテストを別に作成することもできる。
Licensed under a Creative Commons
Attribution–ShareAlike 4.0 License