質問

プロジェクトのどの部分で単体テストを書くのがほぼ不可能、あるいは本当に不可能なのでしょうか?データアクセス?ftp?

この質問に対する答えがある場合、%100 のカバレッジは神話ですよね。

役に立ちましたか?

解決

ここ 見つけました(経由) ハッキングされた マイケル・フェザーが答えとなりそうなことを言っています。

彼は言い​​ます、

次の場合、テストは単体テストではありません。

  • データベースと通信します
  • ネットワークを介して通信します
  • ファイルシステムに触れます
  • 他の単体テストと同時に実行することはできません
  • これを実行するには、環境に対して特別な作業 (構成ファイルの編集など) を行う必要があります。

再び同じ記事で彼は次のように付け加えています。

一般に、単体テストは小規模であることが想定されており、1 つのメソッドまたはいくつかのメソッドの相互作用をテストします。データベース、ソケット、またはファイル システム アクセスを単体テストに取り込むと、実際にはそれらのメソッドに関するものではなくなります。コードと他のソフトウェアの統合に関するものです。

他のヒント

100% のカバー率は神話ですが、それは 80% のカバー率が役に立たないという意味ではありません。もちろん、目標は 100% であり、単体テストと統合テストの間に、目標に近づくことができます。

単体テストで不可能なことは、すべてを完全に予測することです。 奇妙な 顧客が製品に対して行うこと。コードのこれらの驚くべき倒錯を発見し始めたら、必ずそれらのテストをテスト スイートにロールバックしてください。

100% のコード カバレッジを達成することは、ほとんどの場合無駄です。これについては多くのリソースがあります。

単体テストに不可能なことはありませんが、成果は常に逓減します。単体テストが困難なものを単体テストする価値はないかもしれません。

目標は 100% のコード カバレッジでも、80% のコード カバレッジでもありません。単体テストが簡単に書けたからといって、単体テストを書くべきだというわけではありませんし、単体テストを書くのが難しいからといって、その労力を避けるべきだというわけでもありません。

あらゆるテストの目標は、ユーザーが目に見える問題を最も手頃な方法で検出することです。

テストによってフラグが立てられた問題 (誤検知を含む) の作成、保守、診断にかかる総コストは、特定のテストで検出される問題に見合う価値がありますか?

テストで検出された問題が「高価」である場合は、テスト方法を見つけ出し、そのテストを維持することに労力を費やす余裕があります。テストで検出される問題が些細なものである場合、テストの作成 (および保守) は (コードに変更があったとしても) 些細なものである方が良いでしょう。

単体テストの主な目的は、実装エラーから開発者を保護することです。それだけでも、多大な努力は無駄であることがわかるはずです。ある時点以降は、適切な実装を実現するためのより良い戦略が存在します。また、ある時点以降、ユーザーに見える問題は、ユーザー レベルまたは統合テストでのみ検出できる間違ったものを正しく実装したことによるものです。

何をテストしないでしょうか?壊れる可能性のないもの。

コード カバレッジに関しては、実際に作成するコードの 100% を目指す必要があります。つまり、サードパーティのライブラリ コードやオペレーティング システムのコードはテスト済みで提供されるため、そのコードをテストする必要はありません。そうでない限り。その場合は、テストしてみるとよいでしょう。または、既知のバグがある場合は、バグの存在をテストして、バグが修正されたときに通知を受け取ることができます。

GUI の単体テストも、不可能ではないにしても難しいと思います。

テストデータベースを構築できるため、データアクセスが可能です。

一般に、「テストできない」ものは FTP、電子メールなどです。ただし、これらは一般に信頼できるフレームワーク クラスであるため、抽象化の背後に隠した場合はテストする必要はありません。

また、100% のコード カバレッジだけでは十分ではありません。

@GarryShutler

実際に、偽の smtp サーバー (Wiser) を使用して電子メールを単体テストします。アプリケーション コードが正しいことを確認してください。

http://maas-frensch.com/peter/2007/08/29/unittesting-e-mail-sending-using-spring/

同様のことはおそらく他のサーバーでも実行できるでしょう。それ以外の場合は、API をモックできるはずです...

ところで:100% のカバー率は始まりにすぎません...すべてのコードが実際に Bean が実行されたことを意味します 一度....エッジケースなどについては何もありません。

大規模で高価な (リソースや計算時間のコストという点で) セットアップを必要とするテストのほとんどは、統合テストです。単体テストは (理論上) コードの小さな単位のみをテストする必要があります。個別の機能。

たとえば、電子メールの機能をテストしている場合、模擬メーラーを作成するのは理にかなっています。このモックの目的は、コードがメーラーを正しく呼び出すことを確認することです。アプリケーションが実際にメールを送信するかどうかを確認することは、統合テストです。

単体テストと統合テストを区別すると非常に役立ちます。単体テストは非常に高速に実行されるはずです。コードをチェックインする前に、すべての単体テストを簡単に実行できるはずです。

ただし、テスト スイートが多数の統合テスト (データベースなどのセットアップと破棄) で構成されている場合、テストの実行は 30 分を軽く超える可能性があります。その場合、開発者はチェックインする前にすべての単体テストを実行しない可能性が非常に高くなります。

したがって、あなたの質問に答えるには:統合テストとして実装したほうがよいネットの単体テストを実行します (また、ゲッター/セッターのテストも行わないでください。時間の無駄です ;-) )。

単体テストでは、自分の単体に属さないものをテストしてはなりません。コンテキスト内でユニットをテストすることは別の問題です。それが簡単な答えです。

私が使用する基本的なルールは、ユニット (通常はクラス、またはその他のユニット) の境界に触れるものはすべて単体テストし、残りはモックするというものです。データベース クエリが返す結果をテストする必要はありません。ユニットが正しいクエリを吐き出すことをテストするだけで十分です。

これは、テストが難しいだけのものを省略すべきではないという意味ではありません。例外処理や同時実行の問題も、適切なツールを使用すれば十分にテストできます。

「ユニットテストに関しては、テストしないものは何ですか?」 *ゲッターとセッターだけの豆。推論:通常、これは時間の無駄であり、他のことをテストすることに費やしたほうがよいでしょう。

完全に決定的でないものは単体テストでは禁止されます。単体テストが常に同じ初期条件で合格または失敗するようにしたいとします。スレッド、ランダムなデータ生成、時刻/日付、外部サービスなどの奇妙さがこれに影響を与える可能性がある場合は、単体テストでそれをカバーすべきではありません。 。時刻/日付は特に厄介なケースです。通常、現在の日時に機能に依存するのではなく、(コードとテストによって) 操作する日付を挿入するようにコードを設計できます。

ただし、単体テストがアプリケーションの唯一のテスト レベルであるべきではありません。100% の単体テスト カバレッジを達成することは多くの場合時間の無駄であり、すぐに利益が減少します。

より良いのは、一連の高レベルの機能テスト、さらには統合テストを実施して、システムが正しく動作することを確認することです。 「すべてがつながったら」 - ユニットが定義によりテストするもの しないでください テスト。

非常に大規模で複雑なセットアップが必要なもの。もちろん FTP (クライアント) をテストすることはできますが、その場合は FTP サーバーをセットアップする必要があります。単体テストには、再現可能なテスト設定が必要です。提供できない場合はテストできません。

テストすることはできますが、単体テストにはなりません。単体テストとは、ネットワークを越える、データベースにアクセスする、サードパーティの実行/対話、未テスト/レガシーのコードベースに触れるなど、境界を越えないものです。

これを超えるものはすべて統合テストです。

タイトルの質問に対する明白な答えは、API の内部を単体テストすべきではない、他人の動作に依存すべきではない、自分に責任のないものはテストすべきではない、ということです。

残りの部分は、その中にコードを記述できるようにするためだけに十分なはずであり、それ以上でもそれ以下でもありません。

確かに100%のカバー率は良いですね ゴール 大規模なプロジェクトに取り組んでいる場合、ただし、ほとんどのプロジェクトでは、展開前に 1 つまたは 2 つのバグを修正することは、必ずしも徹底的な単体テストを作成する時間に値するものではありません。

フォームの送信、データベース アクセス、FTP アクセスなどを非常に詳細なレベルで徹底的にテストすることは、多くの場合単なる時間の無駄です。書かれているソフトウェアが非常に高いレベルの信頼性 (99.999% のもの) を必要としない限り、単体テストをやりすぎると過剰になり、リアルタイム性が低下する可能性があります。

私は、サードパーティのコードをテストしないことに関する quamrana の回答に同意しません。これは単体テストの理想的な使用法です。ライブラリの新しいリリースにバグが導入された場合はどうなりますか?理想的には、新しいバージョンのサードパーティ ライブラリがリリースされたときに、このライブラリの期待される動作を表す単体テストを実行して、ライブラリが引き続き期待どおりに動作することを確認します。

構成も、単体テストで適切にテストするのが非常に難しい項目です。統合テストとその他のテストは、構成に対して実行する必要があります。これにより、テストの冗長性が減り、多くの時間が解放されます。構成の単体テストを試みることは、多くの場合、簡単ではありません。

FTP、SMTP、I/O は一般に、インターフェイスを使用してテストする必要があります。インターフェイスは、アダプター (実際のコード用) と単体テスト用のモックによって実装する必要があります。

単体テストでは実際の外部リソース (FTP サーバーなど) を実行してはなりません。

単体テストに必要な状態を設定するコードが、テスト対象のコードよりも大幅に複雑になった場合、私は線を引き、機能をテストする別の方法を見つける傾向があります。その時点で、単体テストが正しいとどうやってわかるのかを尋ねる必要があります。

FTP、電子メールなどをサーバー エミュレーションでテストできます。難しいですが可能です。

一部のエラー処理はテストできません。すべてのコードには、決して発生しないエラー処理が存在します。たとえば、Java では、インターフェイスの一部であるため、多くの例外をキャッチする必要があります。ただし、使用されたインスタンスがそれをスローすることはありません。または、考えられるすべてのケースに対して case ブロックが存在する場合のスイッチのデフォルトのケース。

もちろん、不要なエラー処理の一部は削除できます。しかし、将来的にコーディングエラーが発生した場合、これは問題です。

そもそもコードの単体テストを行う主な理由は、コードの設計を検証することです。コード カバレッジを 100% にすることは可能ですが、モック オブジェクトや何らかの形式の分離または依存性注入を使用しないと不可能です。

単体テストはユーザーのためのものではなく、開発者とビルド システムがリリース前にシステムを検証するために使用するものであることに注意してください。そのためには、単体テストを非常に高速に実行し、構成と依存関係の摩擦をできるだけ少なくする必要があります。メモリ内でできる限り多くのことを実行し、テストからのネットワーク接続の使用を避けてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top