私にとっての主な違いは、統合テストは機能が機能しているか、機能していないかを明らかにするということです。これは、現実に近いシナリオでコードにストレスをかけるためです。1つ以上のソフトウェアメソッドまたは機能を呼び出し、期待どおりに動作するかどうかをテストします。
反対に、単一のメソッドをテストする単体テストは、すべての依存関係を明示的に模倣しているため、ソフトウェアの残りの部分が正しく機能しているという(しばしば間違った)仮定に依存しています。
したがって、いくつかの機能を実装するメソッドの単体テストが緑色の場合、それはその機能が機能していることを意味しません。
次のような方法があるとします。
public SomeResults DoSomething(someInput) {
var someResult = [Do your job with someInput];
Log.TrackTheFactYouDidYourJob();
return someResults;
}
DoSomething
顧客にとって非常に重要です。それは機能であり、重要な唯一のものです。そのため、通常はそれをアサートするCucumber仕様を記述します。つまり、機能が動作しているかどうかを確認して通信したいとします。
Feature: To be able to do something
In order to do something
As someone
I want the system to do this thing
Scenario: A sample one
Given this situation
When I do something
Then what I get is what I was expecting for
間違いなく、テストに合格した場合は、機能する機能を提供していると断言できます。これは、ビジネスバリューと呼べるものです。
単体テストを作成するDoSomething
場合は、残りのクラスとメソッドが機能している(つまり、メソッドが使用しているすべての依存関係が正しく機能している)と偽って(モックを使用して)、メソッドが機能していることをアサートする必要があります。
実際には、次のようにします。
public SomeResults DoSomething(someInput) {
var someResult = [Do your job with someInput];
FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
return someResults;
}
これを行うには、依存性注入、ファクトリメソッド、モックフレームワーク、またはテスト対象のクラスを拡張します。
にバグがあるとしLog.DoSomething()
ます。幸い、Gherkin仕様で検出され、エンドツーエンドのテストは失敗します。
機能が機能していないのは、機能してLog
いないためで[Do your job with someInput]
はなく、機能していないためです。そして、ちなみに、[Do your job with someInput]
その方法の唯一の責任です。
また、Log
100の他の機能、100の他のクラスの100の他のメソッドで使用されているとします。
はい、100個の機能が失敗します。しかし、幸いにも、100のエンドツーエンドテストが失敗し、問題が明らかになっています。そして、はい:彼らは真実を語っています。
これは非常に役立つ情報です。製品が壊れていることはわかっています。また、非常にわかりにくい情報です。問題の場所については何もわかりません。根本的な原因ではなく、症状を伝えます。
それでも、DoSomething
ユニットテストは環境にLog
優しいものです。これは、決して壊れないように構築された偽物を使用しているためです。そして、はい:それは明らかに嘘をついています。壊れた機能が動作していることを伝えています。それはどのように役立ちますか?
(DoSomething()
の単体テストが失敗した場合は、必ず確認してください:[Do your job with someInput]
いくつかのバグがあります。)
これが壊れたクラスを持つシステムであるとします:
単一のバグはいくつかの機能を壊し、いくつかの統合テストは失敗します。
一方、同じバグは1つの単体テストを壊すだけです。
次に、2つのシナリオを比較します。
同じバグが1つの単体テストを壊すだけです。
- 壊れたを使用して
Log
いるすべての機能は赤です
- ユニットテストはすべて緑で、ユニットテストのみ
Log
が赤です
実際には、モックを使用して依存関係を削除したため、壊れた機能を使用するすべてのモジュールの単体テストは緑色です。言い換えれば、彼らは理想的な、完全に架空の世界で実行されます。そして、これがバグを分離してそれらを探す唯一の方法です。単体テストはモックを意味します。あざけっていなければ、単体テストではありません。
違い
統合テストは、何が機能していないかを示します。しかし、問題がどこにあるのかを推測するのにそれらは役に立ちません。
単体テストは、バグの正確な場所を示す唯一のテストです。この情報を描画するには、他のすべての依存関係が正しく機能するはずのモック環境でメソッドを実行する必要があります。
そのため、「2つのクラスにまたがる単体テストなのか」という文章は、どうにかして置き換えられていると思います。単体テストは2つのクラスにまたがってはなりません。
この返信は、基本的には私がここに書いたものの要約です。ユニットテストは嘘です。それが私がそれらを愛している理由です。