E2Eテストが大量にあるのは危険かも？膨大化したE2Eテストが及ぼす悪影響

## はじめに

初投稿です。こんにちは！
この記事では、私が過去のプロジェクトで感じた**E2E(End to End)テストの膨大化が及ぼす悪影響**と、それに対する改善案について記載していきます。主に以下の内容について触れていきます。

1. 膨大なE2Eテスト（自動テスト）が及ぼす悪影響
2. E2Eテストが膨大になった原因の考察
3. 信頼性の高い実行結果に、短い時間で到達する自動テストの実現に向けてのアプローチ

ただの感想文ですが、E2Eテストのメンテナンスに時間を取られている方や、テスト実行時間が長くて困っている方に、少しでも参考にしていただければ幸いです。

## 膨大なE2Eテストが及ぼす悪影響
前述した通り、私が在籍していたプロジェクトではE2Eテストのテストケース数が非常に膨大でした。（ざっくり言うと、手動で全てのE2Eテストを実施する場合、1人で2〜3日以上かかる程度のボリュームです）
その結果、主に2つの課題が発生しているように感じていました。

1. テスト実行時間が長すぎる
1. 自動テストのメンテナンスコストが高すぎる

### 1. テスト実行時間が長すぎる
大量のE2Eテストを実行する必要があるため、1回のテスト実行に半日以上時間かかることがありました。これにより、**テストからのフィードバックが遅くなり**、以下のような事象を引き起こしていました。
- バグの早期検知が難しくなる
- リードタイムの増加
- 頻繁にテスト実行するのを避けたくなる
- 開発者のモチベーション低下


### 2. 自動テストのメンテナンスコストが高すぎる

新規実装に伴うE2Eテストのスクリプト更新ももちろん大変ですが、特に厄介だったのは**Flakyテスト（不安定なテスト）の増加**です。
Flakyテストは、コードの変更がないにもかかわらず、テスト結果が成功したり失敗したりするような不安定なテストのことで、原因の特定や修正が非常に難しいです。

E2Eテストが増えるにつれてFlakyテストも増加し、その原因調査や修正に多くの時間を費やすことになりました。
最終的にはテストをメンテナンスしきれず、テストが失敗しても「また失敗かあ。多分コードに問題があるわけじゃなくて、テストが不安定で落ちているだけだろう」となり、**誰も反応しなくなる状態**に陥ってしまいました。
その結果、**テストから得られるフィードバックが全く役立たない**状況になってしまったのです。

## 自動テストの目的を再確認
E2E自動テストが膨大化し、テストによるフィードバックが価値を示さなくなった状態を受け、自動テストの本来の目的を考え直すことにしました。

私自身は、自動テストの目的を「ソフトウェア開発プロジェクトの成長を持続可能なものにすること」だと考えています。この考えは、書籍: 「[単体テストの考え方/使い方](https://x.gd/EZAk2)」を参考にしています。
また、[@t_wada](https://twitter.com/t_wada)さんが非常に的確に表現されている資料を見つけたので、そこから引用させていただきます。

> **自動テストの目的**
信頼性の高い実行結果に短い時間で到達する状態を保つことで、開発者に根拠ある自信を与え、ソフトウェアの成長を持続可能にすること

※参考: [和田卓人氏が考える“自動テストの真の目的”とは？
コスト削減ではなく「変化に対応する力」を得るためのベストプラクティス](https://logmi.jp/tech/articles/330970)


これを自分たちに当てはめて振り返ると、以下のように、自動テストが目的を果たせていたなかったことがわかります。
- `信頼性の高い実行結果`: Flakyテストが多く、結果が不安定...
- `短い時間で到達する`: テスト実行時間が非常に長い...
- `開発者に根拠ある自信を与え`: 不安定なテストの結果に自信が持てない...

## E2Eテストが膨大になった原因の考察
自動テストの目的を達成するための対策を考える前に、E2Eテストが膨大になってしまった原因を振り返ってみました。

様々な要因がありますが、主な原因として「**開発者とQA担当者がテストを分業していた**」ことが挙げられます。
具体的には、**開発者が単体テストの設計・実装を担当し、QA担当者がE2Eテストの設計・実装を行っていた**ため、結果としてE2Eテストのボリュームが増加したと考えています。

E2Eテストが多くなったのは、QA担当者にとって最も馴染みのあるテスト方法であり、様々なテスト観点を網羅的にカバーしようとした結果だと考えています。
この問題については、書籍「[システム運用アンチパターン](https://x.gd/wSbNx)」でも以下のように述べられています。
> エンドツーエンドテストが多くなってしまう理由の１つは、テストの大部分を担当しているチームが開発チームではないことです。自動テストを行っている（すべてではないにしても）多くのQAチームは、UIテストに集中します。なぜならそれが彼らが慣れているアプリケーションやデータとのやりとりのしかただからです。

これは決して開発者やQA担当者が悪いわけではありません。それぞれが自分たちの専門領域でベストを尽くした結果、E2Eテストのボリュームが膨大になり、テストのメンテナンスが追いつかなくなってしまったのです。

## 信頼性の高いテストを短時間で実行するために
E2Eテストが膨大になった原因も踏まえ、ここからは自動テストの目的を実現するために提案した改善案について紹介します。（※提案直後にプロジェクトを抜けてしまったため、効果を確認できていない点はご容赦ください。。。）

### 改善案1. テストピラミッドの実践
まず、E2Eテストのボリューム削減を目指して、**テストピラミッドに基づいたテスト戦略**を提案しました。
テストピラミッドとは、テストレベルごとの理想的な比率を表現したもので、下層に行くほど実行・メンテナンスコストが低く、テストケース数が多くなることが推奨されています。

![image.png](https://cz-cdn.shoeisha.jp/static/images/article/17672/17672_06.png)
参考: [フロントエンドのテスト手法、何がある？　知っておきたいテストとその戦略を網羅的に解説](https://codezine.jp/article/detail/17672)

ピラミッドの上位層に行くほど、テストの忠実性（本物の挙動を反映している度合い）が高くなりますが、次のようなデメリットが顕著になります。
- **テスト実行時間の増加**
- **テストが不安定になる**

これは、E2Eテストが増えれば増えるほど「短時間で信頼性の高い結果を得ること」が難しくなることを示唆しています。そのため、E2Eテストの割合を減らし、単体テストや結合テストに重点を置くべきだと考えました。

そこで以下の取り組みをチームに提案しました。
1. E2Eテスト項目の見直し
1. 結合テストの導入

#### 1. E2Eテスト項目の見直し
E2Eテストでカバーしていた範囲の一部を、より軽量な単体テストや結合テストに移行し、全体のテスト負荷を軽減することを目指しました。これにより、テスト実行時間の短縮とテストの安定性向上を図ることが狙いです。

E2Eテストの見直しに際しては、以下の評価項目に基づいてテスト対象を整理することにしました。
- **機能の重要度**: 機能が利用できなくなった場合の顧客への影響が大きいか
- **手動コスト**: 手動でのテストにかかるコストが高いか
- **自動化コスト**: テスト自動化にかかるコストが高いか
- **低層のテストでカバーできるか**: 単体テストや結合テストで代替可能か

※評価項目は[@tom_asa](https://twitter.com/tom_asa)さんがDevelopers Summit 2024で登壇された[WebシステムやモバイルアプリにおけるUIからの自動テスト事例3選](https://speakerdeck.com/tomasagi/websisutemuyamobairuapuriniokeruuikaranozi-dong-tesutoshi-li-3xuan?slide=33)の内容を参考にさせていただきました。


これにより、E2Eテストの対象を見直し、不要なテストの削減を試みました。

#### 2. 結合テストの導入
テストピラミッドを実現するためには、結合テストの導入が不可欠です。チームには結合テストが存在していなかったため、その導入を提案しました。
結合テストにはさまざまな定義があると思いますが、ここで指しているのは、複数のモジュールが連携して正しく動作するかを確認するテストです。全体の動作よりも、部分的な相互作用に重点を置いています。

E2Eテストとの違いが分かりにくいと思うので、具体例を挙げると以下のようなイメージです。
- **結合テスト**: バックエンドのAPIを呼び出し、期待するデータが返ってくるかを確認する。
- **E2Eテスト**: ユーザーがフォームにデータを入力して送信し、データがデータベースに保存され、最終的に画面に入力内容が表示されることを確認する。

### 改善案2. 開発者とQA担当者の連携強化
次に、E2Eテストの増加を抑制するための施策として、開発者とQA担当者の連携強化を提案しました。

E2Eテストの膨大化を防ぐためには、開発者とQA担当者の間でのテスト戦略の共有が重要になると思います。
以前は分業体制により、テストの責任が分かれていたため、それぞれが自分の視点で必要だと考えるテストを追加し、その結果E2Eテストが増えてしまいました。

この課題に対処するため、**開発者とQA担当者がテスト戦略を共に議論する機会**を設けることを提案しました。
具体的には、各機能の実装前にミーティングを開催し、以下の点を確認します。

- 各機能に対して、どのレイヤーのテストが最適か
- 重複したテストがないか、適切なテストレイヤーでカバーされているか

これにより、テストの重複を防ぎ、テストピラミッド全体で品質を確保することを目指しました。

# まとめ
効果を検証できていないため、少し締まりが悪いですが、今回の出来事から得られた教訓をまとめます。

- **E2Eテストはほどほどに**
    E2Eテストに過度に依存すると、テスト実行時間が長くなり、メンテナンスが難しくなり、結果としてテストの価値が薄れてしまう恐れがあります。そのため、中・長期的に考えると注意が必要だと感じました。
- **持続可能なソフトウェアのためには、適切なテスト戦略が重要**
    テストピラミッドやテスティングトロフィーなどを基に、適切なテスト戦略を立てることが、効率的なテスト実行とメンテナンス性の向上につながると思いました。
- **開発者とQAの壁をなくし、チーム全体で品質を担保する**
    チーム全体で協力し、どのように品質を担保するかを話し合うことが、効果的な自動テストの導入に寄与すると思いました。
    
拙い文章ではありますが、読んでいただきありがとうございました。