テスト自動化はどこまでやるべきか?現場で感じた運用の難しさ

アイキャッチ画像

はじめに

これまでの開発現場では、

  • Django REST framework を用いたAPI開発でのPytest
  • Laravelを用いたAPI開発でのPHPUnit
  • React / TypeScriptでのPlaywrightを用いたE2Eテスト

など、複数のテスト自動化を経験してきました。

どの現場でも、テストコード作成専用の十分な期間が設けられているわけではなく、限られた工数の中で実装と並行しながら対応していました。

本記事では、現場ごとの開発方針に従いながら進めていたことを前提として、テスト自動化の難しさや、形骸化させないために意識していたことについて書いていきます。

API開発での単体テスト

関数単位でのテスト

Django REST framework を用いたAPI開発の現場では、基本的には関数単位でテストコードを作成していました。

この案件では、デザインパターンや継承を多用していたため、テスト時には依存クラスをモックへ差し替える必要がありました。継承構造も深く、テストコード作成よりもモック作成やテスト準備に時間がかかることも少なくありませんでした。

また、すべての関数を網羅的にテストしていたわけではなく、業務影響が大きい処理や複雑なロジック、外部システム連携などを優先してテストしていました。

APIインターフェースを中心としたテスト

一方で、Laravelを用いたAPI開発の現場では、関数単位で細かくテストを書くのではなく、APIのリクエスト・レスポンスやステータスコードを中心に確認するテストコードを作成していました。

内部実装の詳細まではテストせず、「利用者から見てAPIが正常に動作するか」を重視した方針でした。

E2Eテスト

Playwrightを用いたE2Eテストでは、実際のブラウザ操作に近い形で確認できる一方、画面変更の影響を受けやすく、メンテナンスコストが高くなりやすい難しさもありました。

そのため、すべての操作を細かく自動化するのではなく、主要な画面遷移や業務導線を中心にE2Eテストを作成していました。

テスト自動化は工数とのバランスが重要

これまで複数の現場を経験する中で感じたのは、テストコードを長期的に運用し、形骸化を防ぐためには、テスト対象をある程度絞ることも重要だということです。

APIの入口と出口が問題なく動作することを確認できていれば、一定レベルの品質を担保できると感じています。また、不具合発生時にも、どのリクエストやレスポンスで問題が起きているかを把握しやすいメリットがあります。

一方で、関数単位で細かくテストを書きすぎると、

  • 実装変更時に大量のテスト修正が発生する
  • モック作成やテスト準備に時間がかかる
  • テストコード自体の保守コストが高くなる

といった問題もありました。

特に、内部実装の変更だけでもテストが大量に壊れてしまうケースもあり、結果として「テストを修正すること」が目的化してしまう場面もありました。

また、E2Eテストについても、画面変更やUI調整の影響を受けやすいため、細かく作り込みすぎると継続的な運用が難しくなると感じました。

そのため、すべてを網羅的に自動化するのではなく、影響範囲や重要度を考慮しながら、長期的に維持できる粒度でテストを書くことが重要だと感じています。