単体テスト、機能テスト、受け入れテスト、統合テストの違いは何ですか?[閉まっている]


799

単体テスト、機能テスト、受け入れテスト、および統合テスト(および私が言及しなかった他のタイプのテスト)の違いは何ですか?



1
負荷テストを含めるのを忘れたようです!
トークは安いですShow Me Code

回答:


1350

あなたがどこを見ているかによって、あなたはわずかに異なる答えを得るでしょう。私はこの主題についてたくさん読みました、そしてこれが私の蒸留です。繰り返しになりますが、これらはわずかにふさふさしており、他の人は同意しない場合があります。

ユニットテスト

機能の最小単位、通常はメソッド/関数をテストします(たとえば、特定の状態のクラスが与えられた場合、クラスで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つのタイプに焦点を合わせるか、それらを完全に避けることが有利な場合があります。私にとっての主な違いは、一部のテストはプログラマーの観点から物事を検討するのに対し、他のテストは顧客/エンドユーザーの焦点を使用するということです。


19
+1。@Mark Simpson機能テストと受け入れテストを「システムテスト」としてまとめることができますか?エンドツーエンドのテストはどこに適合しますか?(私の好みでは語彙が多すぎます)
Torsten Engelbrecht 2013

3
@フランツ私は、コードのユニットを分離してテストすることでリスクを軽減できる能力と容易さについて話していました。しかし、テストではコードにバグがないことを証明できないため、私が使用した言語は少しゆるいものでした。
Mark Simpson

15
賛成投票にもかかわらず、これは完全に間違っています。単体テストは、「些細な」協力者でさえテストしません。注入された依存関係はすべてモックする必要があります。機能テストは「動作」をテストしません。それらは「関数」のみをテストします。つまり、「f(A)はBを返します」。副作用が重要な場合、それは「行動」です。これらにシステムコールが含まれている場合は、「動作システムテスト」と同様に、「システム」テストでもあります。(下記のtesterab @を参照してください。)「受け入れ」テストは、フルスタックをカバーする「動作システムテスト」のサブセットです。「統合」は上向きにテストし、実際の使用をシミュレートします。すべての依存関係が実際に統合できることをテストします。
cdunn2001

7
@ cdunn2001:心配しないで、建設的な批評は常に良いです:)あなたのコメントは私に知らなかったいくつかのことを教えてくれ、私の用語を少し整理しました。私は常に、テストに熱心な開発者から新しいことを学びたいと思っています。MiškoHeveryのブログを初めて発見したときのことを覚えています-宝の山のようでした:)
Mark Simpson 14年

11
@MarkSimpsonあなたの答えはとても良いですが、機能テストについてもう少し詳しく知りたいです。つまり、私にとって、機能テストと単体テストを区別するのは難しいということです。どうぞよろしくお願いいたします。今後もよろしくお願いいたします。
Andrei Sandulescu 2014年

90

重要なことは、これらの用語が同僚にとってどのような意味を持つかを理解していることです。たとえば、「フルエンドツーエンド」テストと言った場合、グループによって意味が少し異なります。

最近、Googleのテストの命名システムに遭遇しましたが、私はそれが好きです。Small、Medium、Largeを使用するだけで引数をバイパスします。テストがどのカテゴリに該当するかを決定するために、テストの実行にかかる時間、ネットワーク、データベース、ファイルシステム、外部システムへのアクセスなど、いくつかの要素を検討します。

http://googletesting.blogspot.com/2010/12/test-sizes.html

現在の職場では、Small、Medium、Largeの違いがGoogleのものと異なる場合があると思います。

しかし、それはスコープだけでなく、目的についてもです。プログラマー対顧客/エンドユーザーなど、テストの異なる観点に関するマークのポイントは、非常に重要です。


6
さまざまな組織や人々がテストに対して異なる定義を持っている理由についての少しの見通しを与えるのに役立つので、グーグルテストの名前付けの+1。
Mark Simpson

これは、さまざまなレベルのテストを使用する理由とそれから得られるものを説明する非常に優れた記事でもあります。kentcdodds.com
blog

63

http://martinfowler.com/articles/microservice-testing/

Martin Fowlerのブログ投稿では、コードをテストする戦略について(特にマイクロサービスアーキテクチャで)話していますが、そのほとんどはどのアプリケーションにも当てはまります。

彼の要約スライドから引用します。

  • 単体テスト-アプリケーション内のテスト可能なソフトウェアの最小部分を実行して、それらが期待どおりに動作するかどうかを判断します。
  • 統合テスト-コンポーネント間の通信経路と相互作用を検証して、インターフェースの欠陥を検出します。
  • コンポーネントテスト-実行するソフトウェアの範囲をテスト中のシステムの一部に制限し、内部コードインターフェイスを介してシステムを操作し、テストダブルを使用してテスト中のコードを他のコンポーネントから分離します。
  • 契約テスト-外部サービスの境界での相互作用を検証し、それが消費サービスによって期待される契約を満たしていることを表明します。
  • エンドツーエンドテスト-システムが外部要件を満たし、その目標を達成していることを確認し、システム全体をエンドツーエンドでテストします。

ところで、それは素晴らしい記事です。しかし、私は契約テストの目的が完全にはわかりません。コンポーネントと統合テストの観点から、それらは冗長ではありませんか?
ウィレフ2015

一部の言語(Fowler氏が使用)では、クラスの標準定義を使用するときに公開されないインターフェースを実装できます(例:void IMyInterface.MyMethod())。これは論理的に独自のテストを持つことになります。その時点でBDDに戻っていますが、皮肉にもFowler氏は土地を奪っています。
Skarsnik

2
ファウラーの記事ではありません。投稿されたばかりです。コントラクトテストは、クライアントがサービスの使用を開始した後に行われるテストです。次に、特定のクライアントについて何かを壊していないかどうかを確認するテストを作成します(サービスAPIを変更します)。
ラファウŁużyński

@whelephユニット、統合、およびコンポーネントのテストは、主に開発者が厳しく制御できるソフトウェアの内部について説明します。最初の3つの問題は、ソースを変更して問題を修正することを意味します。-契約テストは、機能であなたに約束されたものに触れますが、欠陥に直面して直接変更することができない場合があります。これには、欠陥を修正するだけでなく、これらの考えられる問題を回避するためのサポートコードを追加する必要があります。-したがって、契約仕様で特定の構造であると通知されていても、不正な形式のjsonを返すWebサービスを回避する必要があります。
Yemi Bedu、2016年

31

ユニットテスト -名前が示すように、このメソッドはオブジェクトレベルでテストします。個々のソフトウェアコンポーネントは、エラーがないかテストされます。このテストにはプログラムの知識が必要です。テストコードは、ソフトウェアが意図したとおりに動作するかどうかを確認するために作成されます。

機能テスト -システムの内部動作に関する知識なしで実行されます。テスターは、さまざまな入力を提供し、生成された出力をテストすることにより、要件に従うだけでシステムを使用しようとします。このテストは、クローズドボックステストまたはブラックボックスとも呼ばれます。

受け入れテスト -これは、ソフトウェアがクライアントに渡される前に行われる最後のテストです。これは、開発されたソフトウェアがお客様のすべての要件を満たしていることを確認するために実行されます。受け入れテストには2種類あります。1つは開発チームのメンバーが実行する内部受け入れテスト(アルファテスト)として、もう1つは顧客またはエンドユーザーが(ベータテスト)として実行するテストです。

統合テスト -すでに単体テストが行​​われている個々のモジュールが互いに統合されます。一般に、2つのアプローチに従います。

1)トップダウン
2)ボトムアップ


トップダウンとボトムアップとはどういう意味ですか?統合テストはエンドツーエンドテストと同じですか?
tamj0rd2

18

これはとても簡単です。

  1. 単体テスト:これは、コーディングの知識を持つ開発者が実際に行ったテストです。このテストはコーディング段階で行われ、ホワイトボックステストの一部です。ソフトウェアが開発されると、ユニットとして知られるコードの断片またはコードのスライスに開発されます。そして、これらのユニットの個々のテストは、ステートメントカバレッジの欠落などのある種の人間の間違いを見つけるために開発者が行うユニットテストと呼ばれます。

  2. 機能テスト:このテストはテスト(QA)フェーズで行われ、ブラックボックステストの一部です。以前に記述されたテストケースの実際の実行。このテストは実際にはテスターに​​よって行われ、サイトの機能の実際の結果を見つけ、この結果を期待される結果と比較します。彼らが格差を見つけた場合、これはバグです。

  3. 受け入れテスト:UATとして知られています。そして、これは実際にはテスターだけでなく、開発者、管理チーム、作者、作家、そしてこのプロジェクトに関係するすべての人によって行われます。プロジェクトがバグなしで最終的に提供される準備ができていることを確認するため。

  4. 統合テスト:プロジェクトを完了するために、コードの単位(ポイント1で説明)が互いに統合されます。これらのコード単位は異なるコーディングテクノロジーで記述されている場合や、バージョンが異なる場合があるため、このテストは開発者が行い、コードのすべての単位が他の単位と互換性があり、統合の問題がないことを確認します。


1
@OlegTsyba答えは、質問が答えられてから4年後のものです。
ベンテシャ2017

1
特にこれがこのような複雑なトピックである場合は、「これは非常に単純です」で答えを始めることはできません。
milosmns

6

私はコードをテストするのが初めてです。ユニットテストはほとんど時間の無駄のようです。私は単体テストをしていると思っていましたが、統合テストを行っていて、それから単体テストについて読みましたが、それはばかげているようです。ある点を見逃している可能性があります。
PixMach 2015年

場合は単位が広く定義され、その後、あなたは適切にユニットテストです。テスト実装の詳細に反対します。プライベートクラスは「単体テスト」されるべきではありません。ただし、複数のパブリッククラスがある場合、別のクラスをテストしているときに、1つのクラスを模倣したくなるかもしれません。それが本当の議論です。あるユニット()ライブラリ全体は?(b)ライブラリ内の各パブリッククラス?または(c)、各クラス内の各パブリックメソッド?私は与えられたライブラリを統合コンポーネントとしてテストすることを好みますが、外部の依存関係を模倣または偽造します(それらが高速で信頼できる場合を除く)。だから私はあなたと一緒だと思います。
cdunn2001 2015年

1
@PixMach:実際には逆です。(適切な)単体テストを実施していない場合、あなた(または他の誰か)が将来そのコードを変更する必要がある場合、多くの時間を浪費します。ユニットテストを使用した場合と使用しない場合のコードの保守経験がある場合は、違いがわかります。つまり、単体テストが失敗した場合は、コードのどの部分を修正する必要があるかを正確に把握する必要があります。大規模な受け入れ/統合テストに失敗すると、多くの場合、あなたに言うだけです。それは機能しません。そして、あなたは古い学校のデバッグを始めなければなりません...
Goodsquirrel

@Goodsquirrel、それはあなたが「ユニット」と呼ぶものに依存します。それが問題です。不正なテストはリファクタリング中に削除されます。良いテストはまだ役に立ちます。悪いテストは価値を追加せず、邪魔になります。優れたテストは自己文書化されており、高く評価されています。具体的に見てみましょう。別の値がTrueの場合は値を返し、それ以外の場合はデフォルト値を返すプライベートメソッドがあります。(レガシーコード)そのメソッドはテストする必要がありますか?私はノーと言う。別のプライベートメソッドは、n番目のフィボナッチ数を返します。テストする必要がありますか?はい。
cdunn2001

1
最小の公開コード。大きな違い。
cdunn2001

5

理論的なものではなく、実際的な例でこれを説明します。

開発者がコードを記述します。GUIはまだ実装されていません。このレベルのテストでは、関数が正しく機能し、データ型が正しいことを確認します。テストのこのフェーズは、ユニットテストと呼ばれます。

GUIが開発され、アプリケーションがテスターに​​割り当てられると、彼はクライアントとのビジネス要件を検証し、さまざまなシナリオを実行します。これは機能テストと呼ばれます。ここでは、クライアント要件とアプリケーションフローをマッピングしています。

統合テスト:アプリケーションにHRとFinanceの2つのモジュールがあるとします。HRモジュールは以前に提供およびテストされました。これで、Financeが開発され、テストできるようになりました。相互依存機能も現在利用可能であるため、このフェーズでは、2つの間の通信ポイントをテストし、要件で要求どおりに機能していることを確認します。

回帰テストは別の重要なフェーズであり、新しい開発またはバグ修正の後に行われます。その目的は、以前に機能していた機能を検証することです。


1
「開発者がコードを記述します。GUIはまだ実装されていません。このレベルのテストでは、関数が正しく機能し、データ型が正しいことを確認します。このテストフェーズはユニットテストと呼ばれます」これは正しくありません。GUIは実際には単なる「プラグイン」です。すでにE2EテストをAPI出力に書き込むことができます。(またはユーザーが生成する任意の応答オブジェクト)
user3790897 2018年

4

単体テスト:アプリケーション内の個々のモジュールまたは独立したコンポーネントのテストは単体テストとして知られています。単体テストは開発者によって行われます。

統合テスト:すべてのモジュールを組み合わせてアプリケーションをテストし、モジュール間の通信とデータフローが適切に機能しているかどうかを確認します。このテストも開発者が実行します。

funcionalテストアプリケーションの個々の機能を確認するには、機能テストする平均であります

受け入れテストこのテストは、ビルドアプリケーションが顧客の要件に従っているかどうかにかかわらず、エンドユーザーまたは顧客によって行われ、顧客の仕様は受け入れテストとして知られています。

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