私のプログラムの統合テストがすでにあり、それらすべてが合格した場合、うまくいくと感じています。次に、単体テストを作成/追加する理由は何ですか?とにかくすでに統合テストを作成する必要があるので、統合テストでカバーされていないパーツの単体テストのみを作成します。
統合テストに対する単体テストの利点は
そして、私たちは常に少ないコードを書きたいと思っていますが、ユニットテストを書くにはもっと多くのコードが必要です(主にモックオブジェクトをセットアップします)。いくつかの単体テストと統合テストの違いは、単体テストではモックオブジェクトを使用し、統合テストでは実際のオブジェクトを使用することです。これは多くの重複があり、コードの動作を変更するためのオーバーヘッドが追加されるため、テストでも重複したコードが好きではありません(リファクタリングツールは常にすべての作業を実行できるわけではありません)。
ユニットテストに対する賛成論と反対論を提示しました。 "正の引数の値が負の値のコストを上回るかわかりますか?" =私は確かにそうします:
私の本では、長所は短所を上回っています。
既存の統合テストケースをユニットテストとして再実装することにはあまり価値がありません。
多くの場合、統合テストはtdd以外のレガシーアプリケーション用に作成する方がはるかに簡単です。通常、テスト対象の機能は密結合されているため、単体でのテスト(=単体テスト)は困難/高価/不可能です。
> Then what are the reasons to write/add unit tests?
私の意見では、ユニットテストbeforeを実際のコードで記述した場合、テスト駆動開発が最も効果的です。このようにして、テストを実行するコードは、簡単にテストできる最小限の外部参照で明確に分離されます。
ユニットテストなしでコードが既に存在する場合、コードは簡単なテスト用に作成されていないため、通常、後でユニットテストを作成するのは多くの追加作業になります。
TDDを実行すると、コードを自動的に簡単にテストできます。
統合テストでは、複数のコンポーネントが期待どおりに連携していることのみを確認する必要があります。個々のコンポーネントのロジックが正確かどうかは、単体テストで検証する必要があります。
ほとんどのメソッドにはいくつかの可能な実行パスがあります。 if-then-elseや、予期しない値や単なる間違った値を持つ入力変数などを考えてみてください。通常、開発者はハッピーパス(間違っていない通常のパス)についてのみ考える傾向があります。ただし、他のパスに関する限り、2つのオプションがあります。エンドユーザーがUIで実行するアクションを通じてこれらのパスを探索し、アプリケーションがクラッシュしないことを期待するか、アサートするユニットテストを作成できます。これらの他のパスの動作と必要に応じてアクションを実行します。
あなたがあなたの質問で指摘した理由のいくつかは本当に重要であり、それ自体で単体テストを支持することで非常によく主張することができますが、YMMV。たとえば、統合テストスイートをどのくらいの頻度で実行しますか?統合テストでの私の経験は、遅かれ早かれ遅くなるので、変更を加えるたびに実行されず、バグを挿入してから検出するまでの時間が長くなるということです。
また、あなたがしている大きな間違いはそれを信頼することです
Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.
重要ではありません。ユーザーがバグを見つけることを期待していますか?統合テストから得られたカバレッジを信頼することは私の考えでは危険です。非常に簡単にカバレッジの%を取得できますが、実際にはほとんどテストしていません。
統合テストに対する標準的な参照はJBrainsの投稿だと思います。
http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1
まだ読んでいない場合に備えて。
最後に、IMOは、設計の単体テストから得られるフィードバックが非常に貴重です。直感でデザインを判断し、統合テストに依存することも間違いかもしれません。
コードを変更またはリファクタリングする必要があると予想される場合は、単体テストが不可欠です。ユニットテストは、コードが記述された時点でバグを実証するためだけでなく、コードがさらに記述されたときに新しいバグがいつ現れるかを示すために存在します。
はい、最初に統合テストと単体テストを作成する方がはるかに優れていますが、後で作成する場合でも、それらを使用することには多くの価値があります。