エンドツーエンドテストと単体テストの比較、テストを分離する必要がありますか?


23

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

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

同僚から、この理由は、エンドツーエンドのテストに合格する限り、任意の時点で基になる実装をリッピングおよび変更できるためだと言われました。

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


6
was told by a co-worker that the reason for this is that we can rip out and change the underlying implementation at any point as long as the end-to-end tests pass.-それは単体テストにも当てはまります。エンドツーエンドテストは、単体テストを記述しない口実として使用されているように思えます。
ロバートハーヴェイ

12
単体テストには当てはまりません。メソッドまたはクラスを変更/削除/作成するには、それらのメソッドまたはクラスのすべての単体テストを更新する必要があります。エンドユーザー機能が変更されない限り、エンドツーエンドテストではそうではありません。システムレベルのリファクタリング(エンドユーザー機能の変更なし)であれば、エンドツーエンドのテストを変更する必要はありません。
dietbuddha

2
@dietbuddha、私は一般的な概念が単体テストに当てはまると思いますが、スコープはより小さくなります。
サム

回答:


38

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

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


それは良い答えです。私は両方の値を参照してくださいが、完全に終了試験を終了してすべてのパスをテストするために多くの可能性を見ることの必要性をテストするユニットはそれがより多く行われるように理由を説明するために有用である
ルドルフ・オラー

14
ユニットテストは、問題を迅速に特定できるため、主に価値があると考えています。エンドツーエンドは、すべてが一緒に機能するという自信を与えてくれるため、貴重です。
ジェイソンスウェット

20

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


2
言葉遣いに関する簡単なメモ。厳密な科学ではありませんが、多くの人々は、エンドツーエンドのテストと統合テストは異なるものだと言うでしょう。stackoverflow.com/questions/4904096/…を
sbrattla

6

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

はい、ユニットテストを作成する必要があります。エンドツーエンドのテストは、特にUIコンポーネントに依存している場合、作成が難しく、脆弱です。

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

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

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

あなたは多くのコードをテストしており、カバレッジはかなり良いものになりますが、すべてがうまくいったときのみ幸せなパスをテストしています。フォームに正しい検証があることをどのように確認しますか?そのフォームが複数のページで使用されている場合はどうなりますか?さらに別のエンドツーエンドテストを作成しますか?

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

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

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

自動テストのないプロジェクトにいるときは、どこからでも始めなければならないので、単体テストの作成のしやすさを無視すべきではありません。単体テストから開始する方が簡単かつ迅速であり、幸せな道だけでなく、バ​​グのテストをすぐに開始できます。


:別のデータポイントは、Googleテストブログはこれ以上のエンドツーエンドのテストに言わないgoogletesting.blogspot.ca/2015/04/...
ルドルフ・オラー

5

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

ただし、前述のように、統合テストでエッジケースをキャッチするのはより複雑なので、ユニットテストも実行する必要があります。


1

ユニットテストはユニットの動作を確認しますが、システムの動作を確認します。それぞれの利点とコストは異なります。どちらか一方または両方を行うことができます。

私の仕事では、ユニットテストなしで受け入れテスト駆動開発を行います。私たちは両方を始め、時間をかけて、最終的にはユニットテストがコストを削減し、私たちの利益を超えました。

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


私が心配しているのは、小さな単位ではなく大きなクラスやメソッドにつながる受け入れテストに向けてコーディングすることです。
ルドルフオラー

@omouse:単体テストを書いていないからといって、良いコードを書かない理由はありません。ただし、経験の浅いプログラマーや悪い習慣があるプログラマーがいる場合は、コストよりもメリットの方が大きい場合があります。どちらの場合でも、分析を行い、単純な方程式に変換する必要があります。For Any Practice: Practice iff Benefit > Cost
-Dietbuddha
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.