CoderPadが公式ブログで、エンドツーエンドテスト、統合テスト、単体テスト、静的テストを比較し、統合テストの重要性を解説した。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
コーディング面接に使われるWebサービスなどを手掛けるCoderPadは2022年3月29日(米国時間)、エンドツーエンドテスト、統合テスト、単体テスト、静的テストを比較し、統合テストの重要性を解説したブログ記事を公開した。
概要は以下の通り。
最近では、多様なテストやプログラミング言語に対応した開発者向けツールが出回っている。
エンドツーエンド(E2E)テストでは、「Cypress」「Puppeteer」「Webdriver」「Selenium」などのツールが選択できる。単体テスト、統合テスト、静的テストのツールは、特定の言語向けのものが多い傾向にある。「JUnit」「Jest」「pylint」「mocha」や、「Visual Studio」のビルトイン単体テスト機能など、人気のあるツールを使えば、テストのセットアップを簡単に自動化できる。
だが、どのツールを使うにしても、いつ、どのように使うかを知っておくことが重要だ。
通常、どのテストを使用するかの選択は、テストをする時間/コストと、テスト結果の信頼性のトレードオフに帰着する。以下では、エンドツーエンド、統合、単体、静的の4種類のテストを取り上げ、それぞれをどのように使用すべきかを理解するのに役立つように、コスト/時間と信頼性をそれぞれ4段階で評価する(「1」が最低、「4」が最高)。
E2Eテストでは、ユーザーがアプリケーションでアクションを実行しようとするときに遭遇し得る品質問題を想定し、アプリケーションのユーザー体験全体をテストする。一般的に、最も時間と費用がかかるが、「ユーザーはアプリケーションに不備を感じないだろう」という確信が得られる。
E2Eテストはより高性能なサーバを必要とし、完了までに時間がかかるので、コストもかかる。
E2Eテストに非常に長い時間がかかる一因は、バックエンドサーバに対して呼び出しすることにある。これによって多くのことが分かるが、厄介な事態に陥ることもある。E2Eテストが失敗した場合、フロントエンドコードのせいではなく、バックエンドに問題がある可能性があるからだ。
統合テストでは、バックエンドサービス間やフロントエンドフレームワークのコンポーネント間など、サービス/コンポーネント間の相互作用をテストする。
このテストは、コンポーネントが連携して正しく動作することを確認するために必要だ。単体テストでは、各コンポーネントが正しく動作することが分かるかもしれないが、データエラーやロジックエラーは、コンポーネントを分離してテストしたときにのみ現れるかもしれない。
統合テストでは、テストの実行プロセスをより軽量化できるので、より低コストで実施できる。統合テストに力を入れるべき理由は後述する。
単体テストでは、コードの他の部分との統合をテストするのではなく、コードの特定のビットに集中し、条件付きロジックや関数呼び出しのように、特定の入力セットと出力セットが対応していることを確認する。
このように単体テストは、より小さなロジックやデータ処理に焦点を当てるので、ライブラリのテストに最適だ。
静的テストは、基本的なリンティング(プログラミング言語の文法の間違いやエラーを指摘する)や静的コード解析であり、誤字脱字などの基本的な問題を見つけるのに役立つ。静的テストは最も手軽に、かつ安価に実行できるテストだが、このテストの結果の信頼性は、アプリケーション全体の品質に関してはあまり高くない。
静的テストは、ほぼ全てのIDEと全ての言語で一般的であり、利用されている。
Remix.runのケント・C.・ドッズ氏や、Vercelのギレルモ・ラウチ氏などの著名なソフトウェアエンジニアは、統合テストがE2Eテストよりも低コストで、単体テストよりもカバー範囲が広いことを理由に、もっと統合テストを重視するように提唱している。
ドッズ氏は自身の見解を説明するために、マーティン・ファウラー氏の「テストピラミッド」のアップデート版「テストトロフィー」を作成した。
ファウラー氏のテストピラミッドはよく知られている。コストが上がるとテストのスピードが落ちる傾向があることを示しており、そのために多くの開発者がE2Eテストを最小限に抑え、単体テストを最も多用する。一方、テストトロフィーは少し分かりにくいので、ドッズ氏がどのように説明しているかを紹介する。
「一般的な考え方は、静的解析ツールと統合テストによって、かけたコストに対して“素晴らしい”価値が得られるというものだ。そして単体テストとE2Eテストによって、“良い”価値が得られる。全て利用していただきたい」
統合テストの大きな価値の一つは、E2Eテストと同じようにユーザーの行動をテストできることにある。ユーザーがコンポーネントを単独で使用することはほとんどなく、ほとんどのソフトウェアは、異なるコンポーネント間の相互作用として実行される。このため、統合テストは、特定のロジックの入力と出力をテストするだけの単体テストと比べて、テスト結果の信頼性が高くなる。
ただし、これはもちろん、よく書かれた統合テストにのみ当てはまる。
統合テストが良いかどうかを決める条件の一つは、できる限りモックアウトをしないことだ。その目的は、テストするアプリケーション機能の量を最大化することにある。
これは、一般的なテストのやり方とは異なる。テスト経験のほとんどが単体テストである開発者にとっては、特にそうだ。フロントエンド開発における従来のやり方の顕著な例として、「シャロー(浅い)レンダリング」テストを作成する傾向が挙げられる。
シャローレンダリングテストでは、画面上の複数要素による相互作用ではなく、単一のコンポーネントをテストする。だが、これは悪い慣行になりがちだ。これでは複数のコンポーネント間の統合に関する問題を捉えられないからだ。
現在では、テストフレームワーク全体の一部として統合テストを重視するトレンドがある。このトレンドはしばらく続きそうだ。それにはもっともな理由がある。ドッズ氏の次の言葉がそれを物語っている。
「統合テストは、信頼性とスピード/コストを素晴らしく両立させている。このため、大部分の労力をそこに費やすことが推奨される」
包括的なテスト戦略では、4種類のテストを組み合わせて使用する。だが、統合テストの費用対価値に勝るものはない。
Copyright © ITmedia, Inc. All Rights Reserved.