3

次の 2 つのデータ検証シナリオを検討してください。

どこでもすべてをチェック

1 つ以上の引数を取るすべてのメソッドが実際にそれらをチェックして、それらが構文的に有効であることを確認してください。

長所

  • 非常に細かいチェック粒度。
  • 書かれているコードがある種のライブラリ用である場合、それを使用する開発者が有効なデータを提供できなかった場合に発生する可能性のある損害を制限するようにします。

短所

  • ほとんどの場合必要ないはずのチェックを常に実行するのはコストがかかります。
  • ときどきチェックを追加するのを忘れる可能性はまだあります。
  • より多くのコードが書かれているため、メンテナンスが必要です。

TDDの良さを活かす

データが外部からコードに入力された場合にのみ、データを検証します。内部データが常に構文的に正しいことを確認するには、値を返すすべてのメソッドをチェックするテストを作成します。有効なデータが入力された場合、有効なデータが出力されるようにするため。

長所と短所は、前者のアプローチのものと実質的に入れ替わっています。

今は前者のアプローチを使っていますが、テスト駆動開発を行っているので、後者の方がいいのではないかと考えました。

利点は明らかですが、それでも最初の方法と同じくらい安全かどうかは疑問です.

4

5 に答える 5

1

私の意見では、最初のシナリオでは、2 つの短所が他のすべてを上回っています。

  • ほとんどの場合必要ないはずのチェックを常に実行するのはコストがかかります。
  • より多くのコードが書かれているため、メンテナンスが必要です。

また、TDD はテスト手法ではないため、技術的にはこの質問には関係ありません。もっと後で...

短所を軽減するために、コードを外側内側に分割することを強くお勧めします(あなたが言うように):外側はすべての検証が行われる場所です。うまくいけば、これはGIGOを防ぐために、内側の薄いラッパーにすぎません。内部に入ると、データを再度検証する必要はありません。

TDD については、コードを開発するために TDD を採用することを強くお勧めします (あなたが現在行っているように) 。回帰テスト スイートになるテストの痕跡を残すという追加の利点があります。これで、最初に忘れる可能性のあるチェックを簡単に追加できることを約束して、堅牢な検証を実行する外部コードを自然に開発できます。内部コードは、有効なデータのみを処理することを想定して開発できますが、TDD を使用すると、仕様どおりに機能するという確信が得られます

私が説明したように、TDD を使用して開発しているかどうかに関係なく、2 番目のアプローチを使用すると言っています (ただし、TDD は常に私の最初の選択です)。

于 2009-09-06T21:45:12.270 に答える
0

利点は明らかですが、最初の方法と同じくらい安全かどうかは疑問です。

これは、どれだけうまくテストするかに完全に依存します。

次の 2 つの基準が満たされている場合、これは同様に安全である可能性があります。

  • システムにデータを追加する公開された手段はすべて完全に検証されています
  • データを変換するすべての内部メソッドは、完全かつ適切にテストされています

ただし、これがより簡単になるか、必要なコードが少なくなるかは疑問です。すべてのパブリック エントリ ポイントをチェックするために必要なコードの量は、各メソッドを検証するために必要なコードの量と非常に似ています。エントリ ポイントでより多くのチェックが必要になります。そうでなければ内部でチェックされる可能性があるものをチェックする必要があるからです。

于 2009-09-04T17:05:46.397 に答える
0

長所と短所のリストに 1 つの項目がありません。これは、マニアックなパラメーター チェックよりも単体テストの方がはるかに安全な方法にするのに十分重要な項目です。

WhenWhereを考慮する必要があります。

単体テストの場合、when と where は次のとおりです。

  • いつ:設計時
  • ここで:アプリケーション コード外の専用ソース ファイル内

For overkill data checking they are:

  • when: at runtime
  • where: entangled in the application source code, typically using asserts.

That is the point: code covered by unit testing detects errors at design time when you run the tests, if you are the paranoid and schizofrenic kind of tester (the bests) you write tests designed to break whatever can be, checking each data boundary and perverse input. You also use code coverage tools to ensure every branch of every alternative is tested. You have no limit : tests lies in their own files and do not clutter application. Doesn't matter if you get ten times as many test lines than the actual application code, no run time penalty, no readability penalty.

一方、統合されたオーバーキル テストは実行時にエラーを検出します。. 最悪の場合、ユーザー システムでエラーが検出され、何もすることができなくなります (このエラーが発生したことを聞いたことがあったとしても)。また、あなたが妄想的なタイプであっても、テストを制限する必要があります. アプリケーション コードの 90% をアサーションにすることはできません。可読性の問題、メンテナンス、パフォーマンスの大幅な低下を引き起こします。では、どこで停止しますか: 外部入力のパラメーターのみをチェックしますか? 内部関数のすべての可能なまたは不可能な入力をチェックしますか? すべてのループ不変条件をチェックしていますか? また、フロー データ (グローバル、システム ファイルなど) がなくなったときのテスト動作も変更されましたか? また、アサーション コードにもいくつかのバグが含まれている可能性があることを認識しておく必要があります。アサーションの式が除算を実行するとどうなりますか。DIVIDE-BY-ZERO エラーなどが発生しないようにする必要があります。

もう 1 つの問題は、多くの場合、アサーションが失敗したときに何ができるかがわからないことです。実際のエントリポイントにいる場合は、ユーザーまたは lib ユーザーが理解できるものを返すことができます... 内部関数をチェックしているときに

于 2009-09-08T04:11:54.540 に答える
0

2 番目の方法では、2 つの優れたテスト セットが必要です。確認するだけでなく、

有効なデータが入力された場合、有効なデータが出力されるようにするため。

無効なデータが入力された場合、例外がスローされることも確認する必要があります。データを検証し、無効なデータがある場合はキックアウトする必要があると思います。本番アプリケーションで厄介な ArgumentNullException やその他の不可解なエラーが発生したくない場合は、これが本当に唯一の方法です。ただし、TDD は、そのすべてのチェックの品質を本当に強化することができます (特にFuzz Testingを使用する場合)。

于 2009-09-04T17:06:34.103 に答える