さまざまなテストタイプを組み合わせて、プロジェクトに合った合理的な戦略を実現する方法をご紹介します。
ご利用の再開ありがとうございます。前回の記事では、さまざまなテストタイプに取り組む方法や、テストに含まれる内容について多くの土台を説明し、テストタイプの定義を明確にしました。この小さなミーム画像を覚えていますか?これまで学習したさまざまなタイプのテストがどのように連携するのか、疑問に思われたかもしれません。
次は、それについて詳しく見ていきます。この記事では、これらのテストタイプを組み合わせて妥当な戦略を立て、プロジェクトに適したテストタイプを選択する方法を紹介します。
戦略をいくつかの図形と比較することで、その意味をよりよく理解できます。以下に、それぞれの規模と開発範囲に応じた戦略の一覧を示します。
戦略を詳しく見て、名前の背後にある意味を学びましょう。
テストの目標を決定する: テストで何を達成したいか?
優れた戦略を立てる前に、テストの目標を明確にしましょう。アプリケーションが十分にテストされたと思うのはいつ頃ですか?
高いテスト カバレッジを達成することは、テストに関するデベロッパーの最終的な目標と見なされがちです。しかし、これは常に最適なアプローチでしょうか?テスト戦略を決定する際は、ユーザーのニーズに応えるという重要な要素があります。
デベロッパーは他にも多くのアプリケーションやデバイスを使用しています。この点に関して、あなたは「正常に動作する」ためにこれらのすべてのシステムに依存しているユーザーです。それに伴い、無数のデベロッパーに頼って、アプリケーションやデバイスを機能させるために最善を尽くしています。元の状況に戻すために、デベロッパーである皆さんも、この信頼に応えるよう努めます。したがって、最初の目標は、機能するソフトウェアをリリースし、ユーザーにサービスを提供することです。これは、アプリケーションの品質を確保するために作成するテストについても同様です。Kent C. Dodds 氏が投稿している Static vs Unit vs Integration vs E2E Testing for Frontend Apps の投稿で、
テストがソフトウェアの使用方法に似ているほど、信頼度が高まります。
Kent C. Dodds
ケントさんは、テストで自信がついたと説明しています。ユーザーに近い段階から最適なテストの種類を選択すれば、信頼できるテスト結果が得られやすくなります。つまり、ピラミッドの上位に登るほど、自信が持てるということです。ねえ、ピラミッドとは?
テスト戦略の決定: テスト戦略の選択方法
まず、要件のどの部分が満たされているか確認する必要があります。使用するテストタイプと詳細レベルを確認し、効率的な費用構造を維持しながら、最も確実な結果を得ることができます。多くのデベロッパーは、たとえ話を使ってこのトピックにアプローチしています。ここでは、よく知られているものから順に、最も一般的なものを紹介します。
クラシック: テスト ピラミッド
テスト戦略を模索し始めると、最初のたとえとしてテスト自動化ピラミッドに遭遇するでしょう。マイク・コーンは、著書『Succeeding with Agile』の中でこのコンセプトを紹介しました。その後、Martin Fowler は自身の実践テスト ピラミッドに関する記事で、このコンセプトをさらに発展させました。ピラミッドは次のように視覚的に表現できます。
この図に示すように、テスト ピラミッドは次の 3 つのレイヤで構成されています。
単位。これらのテストは実行が速く、メンテナンスが簡単であるため、ピラミッドのベースレイヤで見つけることができます。これらは分離され、最もマイナーなテストユニットをターゲットとします。たとえば、非常に小さな商品の一般的な単体テストをご覧ください。
統合。これらのテストはピラミッドの真ん中にあります。これは、実行速度が許容範囲内ですが、単体テストよりもユーザーに近づくことができるためです。統合テストの例として、API テストがあります。また、コンポーネント テストをこのタイプに分類することもできます。
E2E テスト(UI テストとも呼ばれます)。これらのテストは、正規のユーザーとその操作をシミュレートします。このようなテストは実行に時間がかかるため、コストが高くなります。ピラミッドの頂点にいます。
信頼度とリソース
前に簡単に説明したように、レイヤの順序は偶然ではありません。優先度と対応する費用が示されています。これにより、各レイヤに対して記述すべきテストの数を明確に把握できます。これは、テストの種類の定義ですでに説明しました。
E2E テストはユーザーに最も近いものであるため、アプリケーションが意図したとおりに動作していることを確実にできます。ただし、完全なアプリケーション スタックとシミュレートされたユーザーを必要とするため、最も高額になる可能性もあります。したがって、テストを実行するために必要なリソースと直接競合することが信頼度になります。
ピラミッドでは、単体テストにより集中し、E2E テストの対象となるケースを厳密に優先することで、この問題を解決しようとします。たとえば、最も重要なユーザー ジャーニーや、不具合が生じやすい場所などです。Martin Fowler が強調するように、コーンのピラミッドで最も重要な 2 つのポイントは次のとおりです。
- 粒度が異なるテストを作成します。
- 高レベルになるほど、実施するテストは少なくて済みます。
ピラミッドが進化しました!テスト ピラミッドを応用した作品
ここ数年、ピラミッドを中心に議論が繰り広げられてきました。このピラミッドは、テスト戦略を単純化しすぎているように見え、多くの種類のテストが省略され、現実世界のすべてのプロジェクトに適していません。誤解を招きかねません。ピラミッドの形は崩れていませんか? これについて Guillermo Rauch はコメントしています。
テストを作成する。そんなに多くありませんほぼ統合。
Guillermo Rauch 提供
このテーマについて最もよく引用される引用の 1 つなので、詳しく見てみましょう。
- 「テストを作成する」。これは信頼を構築するだけでなく、メンテナンスの時間を節約できるからでもあります。
- 「あまり多くありません」。テストが優先されず、メンテナンスの回数が増えるため、100% のカバレッジは必ずしも良いとは言えません。
- 「ほぼ統合」です。ここでも重点が置かれているのが統合テストです。妥当な実行時間を維持しながら、毎日の高い信頼度を提供することで、ビジネス価値を最大化できます。
これにより、テストのピラミッドについてもう一度考え、統合テストに焦点を移すことができます。ここ数年、さまざまな改変が提案されてきたので、最も一般的なものを見てみましょう。
ダイヤモンドをテスト
最初の適応では、テスト ピラミッドに見られるように、単体テストの過度な負担を取り除きます。単体テストのカバレッジが 100% に達したとします。ただし、次にリファクタリングするときは、これらの単体テストの多くを更新する必要があるため、スキップしたくなるかもしれません。こうして浸食される。
その結果、統合テストへの注目が高まるにつれ、次のような変化が起きる可能性があります。
ピラミッドがダイヤモンドに進化します。前の 3 つのレイヤは表示されていますが、サイズが異なるため、ユニットレイヤがカットされています。
- 単位。以前に定義した方法で単体テストを作成します。ただし、その影響が及ぶ傾向があるため、優先的に対処すべき重要なケースに絞って対応する必要があります。
- 統合。ご存じのインテグレーション テストでは、単一のユニットの組み合わせをテストします。
- E2E。このレイヤは、テスト ピラミッドと同様に UI テストを処理します。特に重要なテストケースについてのみ E2E テストを作成するように注意してください。
ハニカムのテスト
Spotify が導入されたもう 1 つの適応は、テストダイヤモンドに似ていますが、マイクロサービス ベースのソフトウェア システムに特化したものです。テスト用のハニカムは、マイクロサービス ベースのソフトウェア システムで作成するテストの粒度、スコープ、数を視覚的に例示したものです。マイクロサービスはサイズが小さいため、マイクロサービスの複雑さが最も大きいのは、サービス自体ではなく、他のサービスとどのようにやり取りするかです。そのため、マイクロサービスのテスト戦略では、主に統合テストに焦点を当てる必要があります。
この形状はハニカム、つまりこの名前を連想させます。次のレイヤがあります。
- テストの統合。Spotify の記事では J. B. Rainsberger は「別のシステムの正確性に基づいて合格または不合格になるテスト」と定義しています。このようなテストには考慮すべき外部依存関係があり、逆にシステムが他のシステムを壊す依存関係にある可能性があります。他の類似例の E2E テストと同様に、これらのテストは特に重要な場合にのみ慎重に使用してください。
- インテグレーション テスト。他の適応と同様に、このレイヤに集中する必要があります。このサービスには、他のサービスと組み合わせて、サービスの正当性をより分離された方法で検証するテストが含まれています。つまり、テストには他のシステムもいくつか含まれ、API テストなどを通じてインタラクション ポイントに焦点を当てます。
- 実装の詳細に関するテスト。これらのテストは単体テストに似ています。単体テストとは、コードの中で自然に分離された部分に重点を置いたテストであるため、内部的には複雑になります。
このテスト戦略について詳しくは、Martin Fowler によるテスト ピラミッドとハニカムの比較に関する投稿と Spotify のオリジナル記事をご覧ください。
トロフィーをテストしています
すでに統合テストの焦点が繰り返されていることが確認できます。しかし、前の記事で紹介した別のタイプは、理論的にはテストしていませんが、それでもテスト戦略で考慮すべき重要な側面です。静的分析は、テストピラミッドと、これまでに見てきたほとんどの適応策には欠けています。統合テストに焦点を当てながら静的分析を考慮したテスト トロフィー適応があります。テスト トロフィーは、ギレルモ ラウチによる以前の引用に由来し、ケント C. Dodds:
テストのトロフィーは、テストの粒度をわずかに異なる方法で表現したものです。次の 4 つのレイヤがあります。
- 静的分析。これは、このたとえ話において重要な役割を果たし、すでに説明したデバッグ手順を実行するだけで、誤字やスタイルの誤りなどのバグを検出できます。
- 単体テスト。最小単位は適切にテストされることを保証するものの、テスト トロフィーではテスト ピラミッドと同じ程度には強調されません。
- 統合。他の適応方法と同様に、最適な方法で費用と信頼度のバランスを取るため、これが主な焦点となります。
- UI テスト。E2E テストと視覚テストを含め、テスト ピラミッドでの役割と同様に、テスト トロフィーのトップに立っています。
テスト トロフィーについて詳しくは、Kent C. Dodds を使用して生成されています。
UI に重点を置いたアプローチ
どれも順調ですが、戦略を「ピラミッド」、「ハニカム」、「ダイヤモンド」と呼んでも、まだ欠けているところがあります。テストの自動化は重要ですが、手動テストも依然として不可欠であることを覚えておいてください。自動テストによってルーティン作業が軽減され、品質保証エンジニアが重要な領域に集中できるようになります。手動テストに代わるものではなく、自動化で補完する必要があります。最適な結果を得るために手動テストと自動化を統合する方法はありますか?
アイスコーンのテストとカニのテスト
実際に、テストのピラミッドには 2 つのバリエーションがあり、UI に重点を置いたテスト方法に重点を置いています。どちらも信頼度が高いという利点がありますが、テストの実行速度が遅いため、当然のことながらコストが高くなります。
1 つ目のテスト アイスコーンはピラミッドのように見えます。手動テスト手順がない場合、テストピザとも呼ばれます。
アイスコーンでは、手動テストや UI テストに重点が置かれており、単体テストには最も重点が置かれていません。テスト戦略について、開発者が少し考えだけで取り組んだプロジェクトでは、テスト戦略が具体化することもよくあります。アイスコードはアンチパターンと考えられていますが、当然のことながら、リソースと手作業の面でコストがかかります。
テスト用カニはテスト用アイスコーンに似ていますが、E2E と視覚テストに重点を置いています。
このテスト戦略にはもう 1 つの側面が含まれています。このテストでは、アプリケーションが機能し、適切に表示されることを検証します。目を向けるカニは、前の記事で定義したビジュアル テストの重要性を強調しています。統合テストはコンポーネント テストと API テストに分けられ、バックグラウンドがさらに進んでいますが、単体テストはさらに二次的な役割を果たします。このテスト戦略について詳しくは、テストカニに関する記事をご覧ください。
これら 2 つのテスト戦略は費用がかかりますが、必要なテストが少ない小規模なプロジェクトや、対処が必要な複雑さが少ないプロジェクトなど、それぞれにメリットがあります。この場合、統合テストに重点を置いた本格的なテスト戦略は、過剰に設計される可能性があります。
これら 2 つのテスト戦略はコストが高くなりますが、テストが少なくて複雑性を多くカバーする必要がない小規模なプロジェクトなどで有用です。この場合、統合テストに重点を置いたフルスケールのテスト戦略が不必要に複雑になる可能性があります。
実践的なアドバイス:戦略を立てましょう!
最も一般的なテスト戦略について学習しました。古典的なピラミッド(テスト ピラミッド)から始めて、多くの適応方法を学びました。それぞれの製品を評価し、プロジェクトに最適な製品を判断する必要があります。この質問に対する答えは、誰もが好む「状況による」から始める必要があります。ただし、精度が下がるわけではありません。
ここで説明したものから、あるいは除外したものから最も適切なテスト戦略を選択できるかどうかは、アプリケーションによって異なります。アーキテクチャと要件に加え、ユーザーとそのユーザーの要件も考慮する必要があります。これらはすべてアプリケーションごとに異なる可能性があります。それは通常のことです。最も重要な目標はユーザーにサービスを提供することであり、教科書の定義ではありません。
多くの場合、実際のテストを個別に分離して定義することは困難です。Martin Fowler 自身も、単体テストのように異なる定義のポジティブな側面を強調しています。Justin Searls は自身のツイートで次のように述べています。
[...] 明確な境界を確立し、迅速かつ確実に実行し、有用な理由がないと失敗する表現力豊かなテストを作成します。
Justin Searls 著
ユーザーが実際に遭遇する可能性のあるエラーを報告するテストに重点を置き、目標から逸脱しないようにします。テストは、単に 100% のカバレッジを実現することや、どのテストタイプのうち何パーセントを作成するかを議論するだけでなく、ユーザーにメリットをもたらすように設計する必要があります。
ユーザーが実際に遭遇する可能性のあるエラーを報告し、目標から気をそらさないテストに重点を置きます。テストは、単に 100% のカバレッジを実現したり、特定のテストの種類のうち何パーセントを記述すべきかについて議論を繰り広げたりするのではなく、ユーザーにとってメリットになるように設計する必要があります。