web-dev-qa-db-ja.com

エンドツーエンドのテストと単体テストの比較、テストは分離すべきですか?

当社では通常、ウェブサイト/ウェブアプリのエンドツーエンドのテストを作成します。つまり、URLにアクセスし、フォームに入力し、フォームを別のURLに送信して、ページの結果を確認します。これは、フォームの検証をテストしたり、HTMLテンプレートに正しいコンテキスト変数があるかどうかをテストしたりするために行います。

また、基になるロジックを間接的にテストするためにも使用します。

この理由は、エンドツーエンドのテストに合格している限り、いつでも基礎となる実装を削除して変更できるためです。

この種のデカップリングが理にかなっているのか、それともコードの小さな単位のテストを書くのを避けるための方法にすぎないのだろうか。

23
Rudolf Olah

エンドツーエンドのテストも必要です。他にどのようにして、すべてのユニットが正しく接続されていることを知ることができますか?非常に単純なコードでは、エンドツーエンドのテストのみでコードを通るすべてのパスをテストすることができますが、レイヤーが増えるほど、そうするのに法外なコストがかかります。

たとえば、3つのレイヤーがあり、それぞれに5つの可能なパスがあるとします。アプリケーション全体のすべてのパスをテストするには、5が必要です。 エンドツーエンドのテストですが、わずか5・3のユニットテストで各ユニットを通るすべてのパスをテストできます。エンドツーエンドのテストのみを行うと、多くのパスが無視されてしまいますが、そのほとんどはエラー処理と境界条件です。

39
Karl Bielefeldt

はい、エンドツーエンドテスト(または統合テスト)は非常に理にかなっていますが、単体テストもそうです。どちらも通常は異なる種類のバグをキャッチするため、理想的には、両方が存在します。したがって、エンドツーエンドのテストは、単体テストがないことの言い訳にはなりません。

20
Doc Brown

さらに数年のコーディングとプロジェクトの作業の後、私は自分の質問に対する回答を提供します。

はい、単体テストを作成する必要があります。エンドツーエンドのテストは、特にUIコンポーネントに依存している場合、作成が難しく、もろくなります。

DjangoまたはRails(または独自のカスタムクラス))のようなフレームワークを使用している場合は、フォームの検証を処理するフォームクラスが必要です。また、レンダリングされたテンプレートとフォームを表示し、GETおよびPOSTリクエストを処理するビュークラスもあります。

エンドツーエンドのテストでは、次のことを行います。

  1. uRLを取得
  2. 有効なデータをフォームに入力します
  3. フォームをURLに投稿する
  4. 有効なフォームの結果として、データベースが更新されているか、何らかのアクションが実行されていることを確認してください

あなたはたくさんのコードをテストしていて、あなたのカバレッジはかなり良いでしょうが、すべてがうまくいった時だけハッピーパスをテストしています。フォームに正しい検証があることをどのように確認しますか?そのフォームが複数のページで使用されている場合はどうなりますか?さらに別のエンドツーエンドのテストを記述しますか?

単体テストでこれをもう一度試してみましょう:

  1. ビューのGETメソッドをテストする
  2. ビューをテストするPOST偽/模擬フォームのメソッド
  3. 有効なデータでフォームをテストする
  4. 無効なデータでフォームをテストする
  5. フォームの副作用をテストする

単体テストを使用することで、より小さなコードをテストすることができ、テストは特定的で記述しやすくなります。これをTDD(テスト駆動開発)と組み合わせると、より高品質のコードが得られます。

no自動テストがあるプロジェクトでは、どこかから開始する必要があるため、単体テストの作成のしやすさは無視しないでください。単体テストから始める方が簡単で高速で、ハッピーパスだけでなく、バ​​グのテストをすぐに開始できます。

6
Rudolf Olah

実際には、エンドツーエンドのテスト、つまり統合テストは、完全に機能するシステムがあることを保証するため、単体テストよりも重要です。ユニットテストはシステムの統合部分をカバーしていません。これは、特に大規模なプロジェクトでは複雑なタスクです。

ただし、前述のとおり、統合テストでEdgeのケースをキャッチするのはより複雑であるため、単体テストも行う必要があります。

5
m3th0dman

ユニットテストはユニットの動作を検証するのに対し、システムの動作を検証します。それぞれのメリットとコストは異なります。どちらか一方または両方を実行できます。

私の仕事では、単体テストなしで受け入れテスト駆動開発を行っています。これは、あなたが説明したものに似ています。私たちは、両方のテストを開始し、時間の経過とともに、最終的に単体テストのコストを削減して、メリットを超えました。

そうは言っても、問題のドメインと環境のコスト/メリットが、さまざまな自動テストプラクティスを含め、開発の実践に従事するための決定を促すものだと思います。私は信仰よりも、すべての実践が、それらをバックアップするために使用するという文脈の中で、経験的な証拠を持つことを好みます。

1
dietbuddha