ユニットテストと統合テストの間のどこに線を引くべきですか?それらは分離すべきですか?


11

私が取り組んできた小さなMVCフレームワークがあります。コードベースは決して大きくはありませんが、2、3のクラスではありません。私はついに思い切ってテストを書き始めることにしました(はい、私はずっとそれをやっていたはずですが、APIはこれまで非常に不安定でした)

とにかく、私の計画は、統合テストなど、テストを非常に簡単にすることです。統合テストの例は、次のようなものに沿って進みます。

偽のHTTP要求オブジェクト-> MVCフレームワーク-> HTTP応答オブジェクト->応答が正しいことを確認

これは状態や特別なツール(ブラウザの自動化など)なしですべて実行できるため、実際には通常の単体テストフレームワーク(私はNUnitを使用)で簡単に実行できます。

さて、大きな質問です。ユニットテストと統合テストのどこに正確に線を引くべきですか?ユニットテストで一度に(可能な限り)1つのクラスのみをテストする必要がありますか?また、統合テストは、ユニットテストプロジェクトと同じテストプロジェクトに配置する必要がありますか?


統合テストでは、コンポーネントの複数の実際の実装を一緒にテストします(実際の実装はモックがないことを意味します)。
ケモダ

1
この質問は、テストとQAに関連しています。したがって、対応するサイト、Stack ExchangeのSQA(sqa.stackexchange.com
-dzieciou

@dzieciouはそれが存在することすら知りませんでした!
アールズ

回答:


19

統合と単体テスト

単体テストと統合テストを完全に分離しておく必要があります。単体テストでは、1つのことと1つのことだけをテストし、システムの残りの部分を完全に隔離する必要があります。ユニットは大まかに定義されていますが、通常はメソッドまたは関数に要約されます。

各ユニットのテストを行うことは理にかなっているので、それらのアルゴリズムが正しく実装されていることがわかり、実装に欠陥がある場合はどこで何が間違っていたかすぐにわかります。

ユニットテスト中に完全に分離してテストするため、スタブオブジェクトとモックオブジェクトを使用して、アプリケーションの他の部分と同様に動作します。これが統合テストの出番です。すべてのユニットを単独でテストするのは素晴らしいことですが、ユニットが実際に連携しているかどうかを知る必要があります。

これは、モデルが実際にデータベースに保存されているかどうか、またはアルゴリズムXが失敗した後に実際に警告が発行されたかどうかを知ることを意味します。

テスト駆動開発

それを一歩下がって、テスト駆動開発(TDD)を見ると、考慮すべきことがいくつかあります。

  1. 実際にパスするコードを記述する前に、ユニットテストを記述します。
  2. テストをパスし、これを達成するのに十分なコードを記述します。
  3. テストに合格したので、次のステップに戻ります。この新しい機能を使用してリファクタリングするものはありますか?すべてがテストでカバーされているため、これを安全に行うことができます。

最初の統合と最後の統合

統合テストは、2つの方法のいずれかでこのTDDサイクルに適合します。事前に書きたい人を知っています。統合テストをエンドツーエンドテストと呼び、エンドツーエンドテストを、ユースケースのパス全体を完全にテストするテストとして定義します(アプリケーションのセットアップ、ブートストラップ、コントローラーへのアクセス、実行、結果、出力などの確認...)。その後、最初の単体テストから始め、合格、2番目の追加、合格などを行います。機能が完了するまで、徐々に統合テストの一部も合格します。

もう1つのスタイルは、ユニットテストごとに機能ユニットテストを構築し、後で必要と思われる統合テストを追加することです。これら2つの大きな違いは、統合テストの場合、最初にアプリケーションの設計を考えざるを得ないことです。この種のことは、TDDはテストと同じくらいアプリケーションの設計に関するものであるという前提に同意しません。

実用性

私の仕事では、すべてのテストが同じプロジェクトにあります。ただし、さまざまなグループがあります。継続的統合ツールは、最初に単体テストとしてマークされているものを実行します。それらが成功した場合にのみ(実際のリクエストを行ったり、実際のデータベースを使用したりするため)統合テストも実行されます。

ちなみに、通常は1つのクラスに対して1つのテストファイルを使用します。

推奨読書

  1. テストによって導かれるオブジェクト指向ソフトウェアの成長この本は、統合テストの最初の方法論の非常に良い例です
  2. dot.netの例を使用した単体テストの技術dot.netの例を使用した単体テストについて:D単体テストの背後にある原理に関する非常に優れた本。
  3. TDDのRobert C. Martin(無料記事):彼がそこにリンクした最初の2つの記事も読んでください。

2

テスト戦略で重要なのは、テストカバレッジです。つまり、すべての機能がテストされていることを示すことができます。

私は一般的であり、あなたの状況には当てはまらないと思われる特定の要件(例:DO178 Level A、IEC61508 SIL 4など)がない限り、クラスまたはモジュールの全機能をテストできる場合(およびシステムレベルで持っていることを実証し、システムレベルのテストで十分です。といった具合です。単体テストは、さらにテストをカバーしていない場合にのみ必要です。

ユニットテストと統合テストのどこに正確に線を引くべきですか?

統合テストは通常​​、より簡単で迅速かつ安価であるため、可能な限り線を引きます...

ユニットテストで一度に(可能な限り)1つのクラスのみをテストする必要がありますか?

スコープに依存しますが、定義により、単体テストは単一のユニットをテストします。ただし、一度に完全なモジュールを完全にテストできる場合は、必要に応じて実行してください。実際、1回のヒットで複数の単体テストを実行しています。

また、統合テストは、ユニットテストプロジェクトと同じテストプロジェクトに配置する必要がありますか?

基本的な理由はありません...独立したテスターがより高いレベルのテストを実行しない限り、実行可能な最小限のインスツルメンテーションのみを発行する必要があります。


2
統合テストがいかに簡単、迅速、または安価であるかを理解できません。私にとっては、3のすべての反対です。そして、統合テストは通常​​、単体テストよりも脆弱です
-Earlz

0

小さなプロジェクトがある場合、すべてのテストを同じプロジェクトにポップするだけです。大きなプロジェクトではこれらの分割が行われるため、必要に応じてそれらを分解することができるようにします。

単体テストでは、通常、ファイル内の1つのクラス(SUT)のみをテストします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.