t-wadaさんの開発生産性の観点から考える自動テストを聴講して悔い改めたこと

t-wadaさんのセッションを聴講したこと

2024/6/29に開発生産性カンファレンスに参加してきました。 その中でなんでもかんでもE2Eテストでも実行してしまうことがあるけど、 悪ではないけどデメリットもあるよ。って話がありました。 speakerdeck.com

スライドP47のアイスクリームコーンとピラミッドの図だけはご参照ください。 頭の中にその図が残っているため、前提になってます。

セッションの概要

アジェンダからざっくりお話は

  • 信頼性の高い
    誤検知(テストとして正常であるはずがエラーになってしまう)や見逃し(エラーがあっても正常にしてしまう)がないこと

  • 実行結果
    実行結果値だしたり、エラー原因が特定しやすいテストを書くこと

  • 短い時間で到達
    確認したい観点を確認できる最小のテストスコープ(単体テスト結合テストなどの粒度)でテストできるようにすること

  • 状態に保つ
    短い時間で到達できるように小さいテストスコープがテストケースが多い状態になっていること

そのために、より小さいテストスコープでテストするよう テストダブル(Mockやスタブ含む)を活用して、移行していこう。って話。

余談

「xUnit Test Patterns」という本にてMock、Stubなどのテスト用の代替クラスの定義が決まって、 人によって概念が違うという議論がなくなったらしいです。 なお本はまだ翻訳されてなさそうでした。

聴講前の私

今の現場でE2Eテストの自動化の話があり、Selenoidやplaywrightを使って、自動化してテストを回すようにしよう。 そうなれば、人の手を介さないから単体テストで回すのと工数に差はないよね。 かつ、他のサブシステムと繋いだりしたテストの方がより本番に近いからテストとしての精度が高いはずだ。 だから、自動化されているのであれば、E2Eテストが増えてもいいじゃないかと勘がてました。

思ってたことのどこが悪かったか

関連する他のサブシステムとの連携のテストを確認したいのであれば、E2Eで確認することは適切だと思います。 APIのフォーマットエラーであれば、E2Eをテストするような環境は不要で、単体レベルでもできるテスト観点かもしれない。

確認したい観点に関わらず、E2Eが本番に近いからE2Eテストで実施すればいいという 雑な考えが間違いであることがセッションを聴講して悔い改めたことでした。

なぜ悪いのか

単体テストでできることをE2Eテスト実施するような テストスコープの大きいテストにて、テストしてしまうことは 時間がかかり、テストが不安定になることがデメリットだった。

時間の観点

よりテストスコープが大きい範囲にすることはデータベースを用意したり、他のサブシステムと繋いだりするため、 単体テストに比べてテストの実行時間がかかってしまう。

単体テストで確認できる観点をE2Eで実施してしまうと、テスト結果が出るまでにも時間がかかってしまう。 すると、エラーがあった場合、エラーの検知が遅れてしまい、修正が遅れてしまう。 これは積み重なっていくとリリースの遅れにもつながってしまう。

エラーを早く検知し修正するためにも確認可能な最小のテストスコープでテストを作り、エラーを早く検知できるようにしないといけない。

不安定なテスト

他のサブシステムとのバージョン合わせだったり、用意したフルスタックの環境に一部不備があったりすると、テストしたい観点と別の原因でエラーになってしまう(誤検知) 誤検知かの判断のために時間もかかってしまうし、 誤検知が増えるテストは信用性が失われて、使われなくなってしまう。

他にも過去の現場で他のサブシステムと連携する環境が複数作れないこともあり、評価環境の使う時期の調整の手間も発生していたこともあった。

不安定さを解消することも大事だが、不安定さのあるE2Eテストより小さいテストスコープで確認できる観点はより安定したテストスコープのテストで確認してあげる方が誤検知のリスクを下げていける。

どう変えようと思ったのか

本番に近い形式のテストで実施すればいいという考えをまず捨てる。

その上で継続して、テストによって何を確認したいのか、何を保証したいのかを明確に決めること。 観点が決まれば、どのテストスコープであれば確認できるが決まるはずだからね。

過去のやらかしはテストダブルを使ってテストスコープ下げることは実践としてやってみようと思ってます。