1

私のオフィスでは、ファイルシステム(DBなど)との対話を主な責務とするクラスの統合テストに加えて、単体テストの必要性について論争があります。

テストされたオブジェクトは他のオブジェクトとまったく相互作用しないため、私たちが行っている統合テストはほとんど単体テストです。テスト統合と呼ぶ唯一の理由は、実際のファイルシステムがテストで使用されることです。そして、テストされたクラスにファイルシステムレイヤーコンポーネントを使用させ、それをテストでモックし(単体テストと呼びます)、実際のファイルシステムの結果ではなく、このコンポーネントとの相互作用をチェックすることが提案されています。この変更の必要性は、私たちが議論することです。


私たちの見解の1つは、次の理由から、単体テストが常に必要であるということです。

  1. 単体テストを書くと、コードがはるかに良くなります
  2. 単体テストがあれば、実際のファイルシステムやファイルの副作用を気にする必要がなく、間違った場所に表示されます
  3. 開発者は、テストされたクラスにファイルシステムのモックを使用させ、そのモックに適切な期待値を設定することで、結果を完全にテストできます。
  4. 単体テストでホワイトボックステストを行うため、モックの期待値をテストされたクラスの特定の内部アルゴリズムに結び付けることは問題ありません。

したがって、単体テストは、そのようなテストされたクラスに対して常に作成する必要があります。また、ファイルシステムレイヤーコンポーネントは、テストの目的でそのクラスによって常に使用される必要があります。


もう1つの観点は、ファイルシステムの相互作用に専念するクラスの特定のエッジケースには単体テストは必要ないということです。理由は次のとおりです。

  1. 実際のファイルシステム(またはその完全なエミュレーション)の代わりに単純なモックを使用するだけでは、テストされたクラスが機能することを適切に検証することはできません。ファイルシステムは非常に複雑なコンポーネントであり、次のようなものです。
    • テストされたクラスは、成功する結果を達成するために多くの異なる方法で機能することができます。モックの期待値は、考えられるシナリオの1つから2つだけをカバーしているため、単体テストでは、期待されるものとは異なる、適切なアルゴリズムを適切に実装するクラスの失敗が誤って示されます。
    • テストされたクラスは、モックによって成功したシナリオとして検出された方法で機能しますが、クラスはまだ正しい結果を生成しません。これは、実際のファイルシステムでは非常に複雑な理由が原因である可能性があります。これらすべての理由は、モックだけでカバーすることは不可能です。
  2. モックと期待値を使用した単体テストは、テストされたクラスの内部アルゴリズムに非常に関連しているため、非常に脆弱です。また、アルゴリズムを正しく変更しても、テストは誤って失敗します。
  3. 統合テストは、クラスに1〜2個のパブリックメソッドがあり、依存関係のみがファイルシステムである場合の単体テストの適切かつ完全な代替手段です。統合テストは、この場合の単体テストと同じ利点を提供します-明確な依存関係、より読みやすいコードなど。

したがって、この場合、ファイルシステムのモックを使用した単体テストは必要ありません。これは壊れやすく、この特定のクラスの場合には正確ではありません。


つまり、要約すると、問題は次のとおり
です。ファイルシステム(DBなど)を操作する主な責任を持つ複雑なクラスがないというエッジケースに対して、統合テストは十分に十分ですか?

このクラスの統合テストと単体テストの唯一の違いは、単体テストではファイルシステムのモックが使用され(クラスは完全に分離されます)、統合テストでは実際のファイルシステムが使用されることです。

古典的な本、あるいは有名な業界関係者の記事やプレゼンテーションへの参照を追加していただければ幸いです。そうすれば、結果として得られる結論を裏付ける非常に強力な基盤を築くことができます。

4

2 に答える 2

1

ここでの簡単な答えは「はい」です。「統合」テストでクラスを完全にテストできます。しかし、もっと良い質問はそうすべきですか?

「ユニットテスト」(外部の依存関係なし)と「統合テスト」(そのような依存関係がある)の定義の違いに夢中になっていると思います。テストの目標は、コードが常に機能していることを確信できるようにすると同時に、その信頼を維持するための関連コストを抑えることです。だからあなたの質問

統合テストは、ファイルシステム(DBなど)を操作する主な責任を持つ複雑なクラスがないというエッジケースに対して十分に十分ですか?

やや不完全です。

私たちの議論における「ユニット」と「統合」の違いの最も有用な部分は、これです。ユニットテストは、作成、保守、および実行がより簡単で安価です。

単体テストを作成するには、コードを知っている必要があります。単体テストが失敗した場合は、コードの変更が原因であることがわかります。統合テストを作成するには、特定のコンテンツを含むファイルの作成、データベースへの行の挿入など、依存関係を設定する必要があります。統合テストが失敗した場合は、コードであるか、依存関係である可能性があります。これらの理由やその他の理由により、統合テストはより複雑であり、したがって、作成、保守、および実行に費用がかかります。

その増加した費用により、開発者は、必要な統合テストの数を最小限に抑えるために、ビジネスロジックをカプセル化するクラスを外部システムとの相互作用を処理するクラスから分離する必要があります。ビジネスロジックは、より安価な単体テストでテストできます。

編集

基になる外部依存関係(つまり、問題のファイルシステム)で複雑な動作を処理する必要があるため、クラス自体が複雑な複雑なロジックを持っている可能性があります。その場合、ファイルシステムをモックすること自体が非常に難しい場合があり適切に設定されたファイルシステムを使用して「統合」テストを作成する方が安価で簡単な場合があります。

心に留めておくべき重要なポイントは、あなたが達成しようとしていることです:許容できるコストでの自信。「統合」テストが十分に安価であれば、すばらしい。'unit'テストを使用して同じ信頼度をより安く得ることができれば、さらに良いでしょう。正確な組み合わせは、目前の問題によって異なります。

于 2013-03-26T14:56:18.900 に答える
0

テストでは、ファイルシステムまたはDBの状態がわかっていることが望ましいでしょう。例として、すでに存在するレコードを挿入しようとしているため、テストが失敗することは望ましくありません。この失敗はコードによるものではなく、DBの問題によるものです。同じことがファイルシステムでも発生する可能性があります。ただし、できる限り最高のテストを作成する必要があります。ファイルシステムなどを簡単にモックできない場合は、ファイルシステムを操作してください。テストが失敗した場合、コードに問題がない可能性があることを理解してください。

ugleテストは、テストなしよりも優れています。--The Way of Testivus http://www.artima.com/weblogs/viewpost.jsp?thread=203994

これで、モックを使用したテストがある場合でも、すべてが正しく接続されていることを確認するためにQAや何らかの統合テストを行う必要がないという意味ではありません。単体テストは、コードの内部が正しく機能することを確認するためのものであり、統合テストでは、すべての要素が連携して機能することがわかります。

使用している言語はわかりませんが、PHPUnitのドキュメントには、DBとファイルシステムのテストに関するいくつかのアイデアが記載されています。

モックと期待値を使用した単体テストは、テストされたクラスの内部アルゴリズムに非常に関連しているため、非常に脆弱です。また、アルゴリズムを正しく変更しても、テストは誤って失敗します。

モックを使用してテストする場合は、アルゴリズムに縛られるべきではありません。テストしているのは、クラスの予想される動作だけです。それがどうなるかではありません。

于 2013-03-26T14:00:30.263 に答える