見出し画像

TotT: メソッドの引数は、絞ってテストしよう。

くぼぴー / note inc.

こんにちは、kubopです。
Googleにはトイレテスト(TotT)という文化があるようで、テストに関するTipsをトイレに貼り出し、テストに関する知識を全社で共有しているらしいです。
昨今はリモート勤務が広まり、TotTの実施は難しく、SlackやBotを用いてもなかなか浸透するかどうか…
そこで、noteに書きつつ自分が勉強するために、少しずつ読んで内容や、所感を書いてみようと思います。
※ 翻訳・解釈の間違いなどあるかもしれません。
その場合はこっそり教えてください。

もっとテストを書いてほしいのです。そう、あなたです。テストは、コードをリファクタリングするときや他の開発者が機能を追加するときに、 あなたを守るセーフティネットであることはもうおわかりでしょう。また、テストがコードの設計に役立つこともご存知でしょう。

私たちは、この秘密兵器(this secret weapon)を世界中の人々と共有し、私たちのテストへの情熱を広めるとともに、あなた自身やあなたの会社の他の人たちに、この重要なトリックやテクニックを楽しく簡単に学んでもらうことにしました。
このブログで定期的にエピソードを紹介し、PDFを提供しますので、プリントアウトしてご自分のバスルーム、廊下、キッチン、月面基地、秘密の地下要塞、億万長者の創業者のプリウスなど、どこにでも貼り付けてください。

Introducing "Testing on the Toilet"

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


この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
くぼぴー / note inc.
note/サーバサイドエンジニアです。 ここ最近はQA活動をしております。 哲学とかそういうのが好きです。 何か新しい考えが浮かんだら記事を書いていきたいです。