単体テスト、機能テスト、受け入れテスト、および統合テスト(および私が言及しなかった他のタイプのテスト)の違いは何ですか?
単体テスト、機能テスト、受け入れテスト、および統合テスト(および私が言及しなかった他のタイプのテスト)の違いは何ですか?
回答:
あなたがどこを見ているかによって、あなたはわずかに異なる答えを得るでしょう。私はこの主題についてたくさん読みました、そしてこれが私の蒸留です。繰り返しになりますが、これらはわずかにふさふさしており、他の人は同意しない場合があります。
ユニットテスト
機能の最小単位、通常はメソッド/関数をテストします(たとえば、特定の状態のクラスが与えられた場合、クラスでxメソッドを呼び出すとyが発生するはずです)。単体テストは特定の1つの機能に焦点を当てる必要があります(たとえば、スタックが空のときにpopメソッドを呼び出すと、がスローされますInvalidOperationException
)。触れるものはすべてメモリ内で実行する必要があります。つまり、テストコードとテスト対象のコードは、次のことを行うべきではありません。
依存性が遅い/理解しにくい/初期化/操作するあらゆる種類の依存関係は、適切な手法を使用してスタブ/モック/あらゆるものにする必要があります。これにより、依存関係が行うことではなく、コードのユニットが行うことに焦点を当てることができます。
つまり、単体テストは可能な限りシンプルで、デバッグが簡単で、信頼性が高く(外部要因が少ないため)、実行が高速で、プログラムの最小のビルディングブロックが統合される前に意図したとおりに機能することを証明するのに役立ちます。注意点は、それらが完全に分離して機能することを証明することはできますが、コードのユニットを組み合わせると爆発する可能性があるということです...
統合テスト
統合テストは、コードのユニットを組み合わせ、結果として生じる組み合わせが正しく機能することをテストすることにより、ユニットテストに基づいて構築されます。これは、1つのシステムの内部、または複数のシステムを組み合わせて有用な何かを行うことができます。また、統合テストと単体テストを区別するもう1つのことは、環境です。統合テストでは、スレッドを使用したり、データベースにアクセスしたり、すべてのコードやさまざまな環境の変更が正しく機能したりするために必要なことを何でも実行できます。
シリアライゼーションコードをいくつか作成し、ディスクに触れずにその内部をユニットテストした場合、ディスクにロードして保存するときにそれが機能することをどのように確認しますか?ファイルストリームをフラッシュして破棄するのを忘れたのかもしれません。多分あなたのファイル許可は不正確であり、あなたはメモリストリームで使用する内部をテストしました。確実に調べる唯一の方法は、本番環境に最も近い環境を使用して「実際に」テストすることです。
主な利点は、ユニットテストでは配線のバグ(たとえば、クラスAのインスタンスが予期せずBのnullインスタンスを受け取る)などのバグと環境バグ(私のシングルCPUマシンで正常に動作しますが、同僚の4コアマシンはテストに合格できません)。主な欠点は、統合テストがより多くのコードに触れ、信頼性が低下し、障害の診断が難しくなり、テストの維持が難しくなることです。
また、統合テストは、完全な機能が動作することを必ずしも証明しません。ユーザーは私のプログラムの内部の詳細を気にしないかもしれませんが、私はそうします!
機能テスト
機能テストでは、特定の入力の結果を仕様と比較することにより、特定の機能が正しいかどうかを確認します。機能テストは、中間結果や副作用ではなく、結果のみを扱います(xを実行した後、オブジェクトyが状態zになることを気にしません)。これらは、「引数が2の関数Square(x)を呼び出すと4を返す」などの仕様の一部をテストするために作成されています。
受け入れテスト
受け入れテストは2つのタイプに分かれているようです:
標準の受け入れテストでは、アプリケーションの機能が仕様を満たしているかどうかを確認するために、システム全体(Webブラウザ経由でWebページを使用するなど)でテストを実行します。たとえば、「ズームアイコンをクリックすると、ドキュメントビューが25%拡大されます。」実際の連続した結果はなく、単に成功または失敗の結果です。
利点は、テストが簡単な英語で記述され、ソフトウェア全体として機能が完全であることを保証することです。欠点は、テストピラミッドのレベルを1つ上げたことです。受け入れテストはコードの山に触れるため、失敗を追跡するのは難しい場合があります。
また、アジャイルソフトウェア開発では、ユーザー受け入れテストには、開発中にソフトウェアの顧客によって/のために作成されたユーザーストーリーを反映するテストを作成することが含まれます。テストに合格した場合、ソフトウェアはお客様の要件を満たしている必要があり、ストーリーは完全であると見なすことができます。受け入れテストスイートは、基本的に、システムのユーザーが使用する言語でのテストを記述するドメイン固有の言語で記述された実行可能な仕様です。
結論
それらはすべて補完的です。1つのタイプに焦点を合わせるか、それらを完全に避けることが有利な場合があります。私にとっての主な違いは、一部のテストはプログラマーの観点から物事を検討するのに対し、他のテストは顧客/エンドユーザーの焦点を使用するということです。
重要なことは、これらの用語が同僚にとってどのような意味を持つかを理解していることです。たとえば、「フルエンドツーエンド」テストと言った場合、グループによって意味が少し異なります。
最近、Googleのテストの命名システムに遭遇しましたが、私はそれが好きです。Small、Medium、Largeを使用するだけで引数をバイパスします。テストがどのカテゴリに該当するかを決定するために、テストの実行にかかる時間、ネットワーク、データベース、ファイルシステム、外部システムへのアクセスなど、いくつかの要素を検討します。
http://googletesting.blogspot.com/2010/12/test-sizes.html
現在の職場では、Small、Medium、Largeの違いがGoogleのものと異なる場合があると思います。
しかし、それはスコープだけでなく、目的についてもです。プログラマー対顧客/エンドユーザーなど、テストの異なる観点に関するマークのポイントは、非常に重要です。
http://martinfowler.com/articles/microservice-testing/
Martin Fowlerのブログ投稿では、コードをテストする戦略について(特にマイクロサービスアーキテクチャで)話していますが、そのほとんどはどのアプリケーションにも当てはまります。
彼の要約スライドから引用します。
- 単体テスト-アプリケーション内のテスト可能なソフトウェアの最小部分を実行して、それらが期待どおりに動作するかどうかを判断します。
- 統合テスト-コンポーネント間の通信経路と相互作用を検証して、インターフェースの欠陥を検出します。
- コンポーネントテスト-実行するソフトウェアの範囲をテスト中のシステムの一部に制限し、内部コードインターフェイスを介してシステムを操作し、テストダブルを使用してテスト中のコードを他のコンポーネントから分離します。
- 契約テスト-外部サービスの境界での相互作用を検証し、それが消費サービスによって期待される契約を満たしていることを表明します。
- エンドツーエンドテスト-システムが外部要件を満たし、その目標を達成していることを確認し、システム全体をエンドツーエンドでテストします。
ユニットテスト -名前が示すように、このメソッドはオブジェクトレベルでテストします。個々のソフトウェアコンポーネントは、エラーがないかテストされます。このテストにはプログラムの知識が必要です。テストコードは、ソフトウェアが意図したとおりに動作するかどうかを確認するために作成されます。
機能テスト -システムの内部動作に関する知識なしで実行されます。テスターは、さまざまな入力を提供し、生成された出力をテストすることにより、要件に従うだけでシステムを使用しようとします。このテストは、クローズドボックステストまたはブラックボックスとも呼ばれます。
受け入れテスト -これは、ソフトウェアがクライアントに渡される前に行われる最後のテストです。これは、開発されたソフトウェアがお客様のすべての要件を満たしていることを確認するために実行されます。受け入れテストには2種類あります。1つは開発チームのメンバーが実行する内部受け入れテスト(アルファテスト)として、もう1つは顧客またはエンドユーザーが(ベータテスト)として実行するテストです。
統合テスト -すでに単体テストが行われている個々のモジュールが互いに統合されます。一般に、2つのアプローチに従います。
1)トップダウン
2)ボトムアップ
これはとても簡単です。
単体テスト:これは、コーディングの知識を持つ開発者が実際に行ったテストです。このテストはコーディング段階で行われ、ホワイトボックステストの一部です。ソフトウェアが開発されると、ユニットとして知られるコードの断片またはコードのスライスに開発されます。そして、これらのユニットの個々のテストは、ステートメントカバレッジの欠落などのある種の人間の間違いを見つけるために開発者が行うユニットテストと呼ばれます。
機能テスト:このテストはテスト(QA)フェーズで行われ、ブラックボックステストの一部です。以前に記述されたテストケースの実際の実行。このテストは実際にはテスターによって行われ、サイトの機能の実際の結果を見つけ、この結果を期待される結果と比較します。彼らが格差を見つけた場合、これはバグです。
受け入れテスト:UATとして知られています。そして、これは実際にはテスターだけでなく、開発者、管理チーム、作者、作家、そしてこのプロジェクトに関係するすべての人によって行われます。プロジェクトがバグなしで最終的に提供される準備ができていることを確認するため。
統合テスト:プロジェクトを完了するために、コードの単位(ポイント1で説明)が互いに統合されます。これらのコード単位は異なるコーディングテクノロジーで記述されている場合や、バージョンが異なる場合があるため、このテストは開発者が行い、コードのすべての単位が他の単位と互換性があり、統合の問題がないことを確認します。
過度のモックと純粋な単体テストに対するいくつかの(比較的)最近のアイデア:
理論的なものではなく、実際的な例でこれを説明します。
開発者がコードを記述します。GUIはまだ実装されていません。このレベルのテストでは、関数が正しく機能し、データ型が正しいことを確認します。テストのこのフェーズは、ユニットテストと呼ばれます。
GUIが開発され、アプリケーションがテスターに割り当てられると、彼はクライアントとのビジネス要件を検証し、さまざまなシナリオを実行します。これは機能テストと呼ばれます。ここでは、クライアント要件とアプリケーションフローをマッピングしています。
統合テスト:アプリケーションにHRとFinanceの2つのモジュールがあるとします。HRモジュールは以前に提供およびテストされました。これで、Financeが開発され、テストできるようになりました。相互依存機能も現在利用可能であるため、このフェーズでは、2つの間の通信ポイントをテストし、要件で要求どおりに機能していることを確認します。
回帰テストは別の重要なフェーズであり、新しい開発またはバグ修正の後に行われます。その目的は、以前に機能していた機能を検証することです。
単体テスト:アプリケーション内の個々のモジュールまたは独立したコンポーネントのテストは単体テストとして知られています。単体テストは開発者によって行われます。
統合テスト:すべてのモジュールを組み合わせてアプリケーションをテストし、モジュール間の通信とデータフローが適切に機能しているかどうかを確認します。このテストも開発者が実行します。
funcionalテストアプリケーションの個々の機能を確認するには、機能テストする平均であります
受け入れテストこのテストは、ビルドアプリケーションが顧客の要件に従っているかどうかにかかわらず、エンドユーザーまたは顧客によって行われ、顧客の仕様は受け入れテストとして知られています。