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