7

同僚のためにいくつかのコードをレビューしていて、単体テスト クラスで次のようなテストに出くわしました。

// setup
Foo f = ...
FooToBarConverter ftb = ...
Bar b = ftb.Convert(f); // It is easier to create a Bar by converting it from a Foo than making one 'from scratch'

// test
systemUnderTest.DoSomething(bar);

// assert
Assert.IsTrue(...)

DoSomething() メソッドをカバーする唯一のテストであるため、FooToBarConverter とテスト対象のシステムをテストしているため、明らかにこれは統合テストです。このテストを統合テスト ソリューションに移行することを提案しましたが、これにより単体テストのコード カバレッジが低下します。私たちは 100% の単体テスト コード カバレッジを目指しています (もちろん、100% カバレッジは目的そのものではなく、目的を達成するための手段であり、100% カバーされたコードは必ずしも 100% 正しいコードであるとは限りません)。

統合テストを外した場合、カバレッジを元に戻すために単体テストを作成する理由はありますか?

それとも、100% の単体テスト カバレッジで間違ったことを目指しているのでしょうか? すべてのテストを組み合わせて 100% のカバレッジを目指すべきでしょうか (またはまったく 100% を目指すべきでしょうか)。

ありがとうございました。

編集/更新:

これは、テスト対象のシステムを適切に単体テストする方法に関する質問ではありません (これが単体テストではない理由を知っており、それを適切に単体テストに変換する方法も知っています)。 FooToBarConverter. テスト対象システムのコード カバレッジについて意見が欲しい: テスト対象システムの統合テストは十分か? それとも単体テストも必要ですか?

4

1 に答える 1

6

ここでの答えは「場合による」と思います。

  • クラスの単体テストを完全にカバーしているFooToBarConverter場合は、おそらく の統合テストだけで問題ないでしょう。これは、実際のクラスがこのコンテキストで期待どおりに動作し、テストの結果に誤った影響を与えないことsystemUnderTestを自信を持って言えるからです。FooToBarConverter

  • 一方で、このテストが何をチェックしているのか具体的には不明です。systemUnderTest有効な が与えられたときの動作、または純粋に偶然のアクターでFooToBarConverterあるその他の予想される副作用を調べていますか? (つまり、これが の間接テストではないことを確信していますか?)systemUnderTestFooToBarConverterbar

個人的には、適切な「純粋な」単体テスト (のモックまたはスタブを使用FooToBarConverter)も行うsystemUnderTestことをお勧めします。

  • リグレッションの管理が容易になります。将来、ユニットテストが失敗するように何らかの変更が行われると仮定しますFooToBarConverter。そのため、この統合テストも失敗する可能性が非常に高くなります。これは、失敗したテストを見て、統合テストの失敗を無視できること、および FooToBarConverter テストのみを修正する必要があることを知らない人にとっては混乱を招く可能性があります。些細なことですが、いつか重要な 5 分間を節約できるかもしれません :)

  • systemUnderTest否定的なケース (壊れた/無効な/null が与えられたときの動作) をどのようにテストしますFooToBarConverterか? とにかく、これらの種類のケースではおそらくスタブ/モックを使用して単体テストを作成する必要があるため、同じプロジェクト/テストクラスでも適切なケースの単体テストを作成する必要があるため、はるかに明確です-そうでない場合は、単体テスト プロジェクトと統合テスト プロジェクトの両方でコード カバレッジを集計し、systemUnderTest完全にカバーされていることを確認します...

また、100% のコード カバレッジについて心配する必要はありません。あると便利ですが、実際に目にすることはめったにありません。これは、優れた設計慣行に対する SOP という意味でもありません。単純な現実として、100% 完璧な設計はありません。したがって、クラスをリファクタリングしてすべての依存関係を注入したり、注入したりできるようにするための時間/リソース/意志がない場合があることが予想されます。すべてのインターシーム相互作用などにインターフェースを使用できます。

それが役立つことを願っています。

于 2013-11-01T10:12:56.527 に答える