典型的なWebアプリケーションでの単体テストと機能テストの適切なバランスは何ですか?
-
10-07-2019 - |
質問
単体テストの作成と保守は安価ですが、すべてのシナリオをカバーしているわけではありません。それらの間の適切なバランスは何ですか?
解決
ブライアンマリックの象限自動化されたテストでは、ビジネスとテクノロジーが対面し、プログラミングと批評製品がサポートされます。
このフレームワークでは、バランスの問題になりますが、今何が必要ですか?
他のヒント
これら2つのタイプのテストの意図と範囲を区別することが重要です:
-
a 単体テストは通常、モジュール/クラスレベルで特定の機能をテストします。 、例えばcreate-X、update-Y、foo-the-bar、compact-the-whizbangなど。1つのクラスに複数の単体テストを含めることができます
-
a 機能テストは、「受け入れテスト」とも呼ばれ、通常、最も外側のインターフェースから処理の終わりまでのユースケースシナリオ、例えばユーザーインターフェースからデータベースへ、そして再び戻って、入力プロセスから通知ユーティリティなどへ。
これらの2種類のテストは、互換性がありません、一般的には互いに素です。したがって、それらの間の「バランス」を打つという概念は意味をなしません。必要な場合も必要ない場合もあります。
テストフレームワークの各タイプのテストのコーディングのしやすさについて言及している場合、それは別の質問ですが、フレームワークの使用(たとえば、NUnitとユーザーボット)はタイプ/テストの性質。
最高の「バランス」は、一般的に、信頼性と完全性を単体テストし、クライアントの受け入れを機能テストすることです
Steven Loweは、ユニットテストと機能テストは非常に異なる目的で使用されるため、ユニットテストと機能テストの間にはトレードオフがないことに同意します。
単体テストは、メソッドと型の検証、および回帰テストに関するものです。機能テストは、機能、シナリオ、および実行可能性テストに関するものです。私の意見では、重複はほとんどありません
それが役立つ場合、ここに私のテストカテゴリがあります。
開発者は内部から始まり、外側に向かって、コードに焦点を当てます:
- アサーション-データフローと構造の検証
- デバッガ-コードフローとデータの検証
- 単体テスト-各機能を検証します
- 統合テスト-サブシステムの検証
- システムテスト-機能の検証
- 回帰テスト-欠陥が修正されたままであることを確認します
- セキュリティテスト-システムに簡単に侵入できないことを確認します。
テスターは外部から始め、機能に焦点を当てて内向きに作業します:
- 受け入れテスト-エンドユーザーの要件を確認します
- シナリオテスト-現実の状況を確認する
- グローバルテスト-実行可能な入力を確認します
- 回帰テスト-欠陥が修正されたままであることを確認します
- ユーザビリティテスト-システムが使いやすいことを確認します
- セキュリティテスト-システムに簡単に侵入できないことを確認する
- コードカバレッジ-そのままのコードのテスト
- 互換性-以前のリリースとの互換性
- 癖と粗いエッジを探しています。
エンドユーザーは外部から作業し、通常はほとんど焦点がありません:
- 受け入れテスト-エンドユーザーの要件を確認します
- シナリオテスト-現実の状況を確認する
- ユーザビリティテスト-システムが使いやすいことを確認します
- 癖と粗いエッジを探しています。
私が現在取り組んでいるアプリでは、おそらく機能テストに対する10:1ユニットがあります。単体テストは、DBからのエンティティの取得、db /ネットワーク接続のエラー処理テストなどのような単純なものです。これらは、数分以内に迅速に実行され、開発者によって毎日実行されます。
機能テストは少数ですが、キッチンシンクアプローチである傾向があります-ユーザーは注文を完了することができますか?これらを実行するには数週間かかり、通常はリリースサイクルを完了します。
現在のプロジェクトのユニットテスト範囲は約60%で、すべてのユーザーストーリーにはセレンテストのユーザーストーリーのハッピーデイカバレッジがあり、一部のユーザーストーリーには追加のカバレッジがあります。
これについては継続的に議論しています:ますます不合理なシナリオの単体テストカバレッジをより高いカバレッジにプッシュするポイントは本当にありますか?
セレンのテストを拡大すると、ビジネス価値のあるもののテスト範囲が広がるという議論があります。顧客は、失敗する可能性のある単体テストのコーナーケースを本当に気にしますか?
セレンのテストが得られると、ビジネス価値のある新しいテストを作成するコストが減少します。私たちにとっては、単体テストと同じくらい簡単です。
実行時のコストは別の問題です。これらのテストを常に実行している小さなボックスのクラスターがあります。
したがって、Webテストを好む傾向があります。おそらく、Webテストを書くことに長けており、それが否定できないビジネス価値を提供しているからでしょう。
当初は、受け入れテストの初期コスト要因のために、機能/受け入れテストよりも単体テストを優先することに重点を置いていました。しかし、時間が経つにつれて、私は哲学を変え、可能な限り受け入れテストを選択し、受け入れテストが私のニーズを満たすことができない場合に単体テストのみを使用することを強く支持しています。
単体テストよりも受け入れを選択する背後にある基本的な合理性は、 SOLID コード。実装はリファクタリングなどで大幅に変更できる必要がありますが、すべてのビジネスケース(受け入れテスト)は変更されないままで、受け入れ可能なシステムの動作を証明できる必要があります(テストは合格)。単体テストでは、テストが実装コードに自然に強く結び付けられることがよくあります。テストコードであるにもかかわらず、コードであり、既知の強力な結合は避ける必要があります。受け入れテストを選択することで、成功のスパイラルをたどり、よく計画された消耗品の分離されたAPIを作成し、テストを強制的に変更することなく舞台裏で実装を変更できます。また、開発者の実装の考え方は、ビジネスシステムの動作の考え方と一致しています。最終的には、これらすべてがビジネスとコーダーの満足度に優れていることがわかりました。
理論的な観点から、受け入れテストを介してコードの一部をテストできないのはなぜかと疑問に思うことがよくあります。 IE-有効なビジネスシナリオの一部ではない場合、そのコードは価値を高めるのでしょうか、それとも現在のところ、それだけでコストがかかりますか?
さらに、受け入れテストを適切にコメント/文書化すると、それらのコメント/文書は通常、システムの最新かつ正確な言語になります。これにより、他の価値の低い文書化アプローチを回避できます。単体テストは、そのような「ビジネス用語」の形には向いていません。コミュニケーション。
最後に、私は個人的な開発からこの視点を形成していませんが、「非常に企業」のいくつかの異なるプロジェクトチームで成功していることが証明されています。作業環境。
テストは迅速に実行され、問題の特定に役立ちます。 単体テストでは、問題のモジュールのみをテストすることでこれを行うことができます。 ただし、ほとんどのWebシナリオでは、機能/統合/受け入れテストを十分迅速に実行できます。
一度、単体テストが「実行可能な要件」であることを読んだことがあります。テストがビジネス要件の証明に焦点を合わせていない場合、それは実際には役に立ちません。詳細な要件(およびそれが酸性テスト)がある場合は、考えられる各シナリオを実行するための多数の単体テストを作成し、データ構造アルゴリズムとロジックの整合性を確認します。要件ではないものをテストしているが、テストに合格するためには真実でなければならないことがわかっている場合は、要件が欠落している可能性が高くなります。