Debug.Assert が適切な選択である可能性がある場合、さらに 4 つのケースを追加すると考えました。
1)ここで言及されていないのは、Asserts が自動化されたテスト中に提供できる追加の概念的なカバレッジです。簡単な例として:
より高いレベルの呼び出し元が、追加のシナリオを処理するためにコードの範囲を拡張したと考えている作成者によって変更された場合、理想的には (!) この新しい条件をカバーする単体テストを作成します。その場合、完全に統合されたコードが正常に動作しているように見える場合があります。
ただし、実際には微妙な欠陥が導入されていますが、テスト結果では検出されていません。この場合、呼び出し先は非決定論的になり、たまたま期待される結果しか提供しません。または、見過ごされていた丸め誤差が発生した可能性があります。または、他の場所で均等にオフセットされたエラーが発生しました。または、要求されたアクセス権だけでなく、付与されるべきではない追加の権限が付与されます。等。
この時点で、呼び出し先に含まれる Debug.Assert() ステートメントは、単体テストによって駆動される新しいケース (またはエッジ ケース) と組み合わされて、テスト中に元の作成者の仮定が無効になり、コードが無効になってはならないという非常に貴重な通知を提供できます。追加審査なしでリリースされます。単体テストを伴うアサートは完璧なパートナーです。
2)さらに、一部のテストは簡単に作成できますが、最初の仮定を考えると、コストが高く不要です。例えば:
特定の保護されたエントリ ポイントからのみオブジェクトにアクセスできる場合、すべてのオブジェクト メソッドからネットワーク権限データベースに対して追加のクエリを実行して、呼び出し元にアクセス許可があることを確認する必要がありますか? 確かにそうではありません。おそらく理想的なソリューションには、キャッシングまたはその他の機能拡張が含まれますが、設計上は必要ありません。Debug.Assert() は、オブジェクトが安全でないエントリ ポイントにアタッチされるとすぐに表示されます。
3)次に、場合によっては、製品がリリース モードで展開されたときに、その操作のすべてまたは一部に対して有用な診断インタラクションがない場合があります。例えば:
組み込みのリアルタイム デバイスであるとします。不正なパケットに遭遇したときに例外をスローして再起動すると、逆効果になります。代わりに、デバイスは、出力にノイズをレンダリングする点でも、ベストエフォート動作の恩恵を受ける可能性があります。また、ヒューマン インターフェイスやロギング デバイスがなく、リリース モードでデプロイされた場合、人間が物理的にアクセスできない場合もあります。エラーの認識は、同じ出力を評価することによって提供されるのが最適です。この場合、リベラルなアサーションと完全なプレリリース テストは、例外よりも価値があります。
4)最後に、呼び出し先が非常に信頼できると認識されているという理由だけで、一部のテストは不要です。ほとんどの場合、コードが再利用可能であるほど、信頼性を高めるために多くの努力が払われています。したがって、呼び出し元からの予期しないパラメーターに対しては Exception に、呼び出し先からの予期しない結果に対しては Assert するのが一般的です。例えば:
コアString.Find
操作で-1
、検索基準が見つからない場合に a が返されると記述されている場合、3 つではなく 1 つの操作を安全に実行できる可能性があります。ただし、実際に が返さ-2
れた場合は、適切な対応策がない可能性があります。より単純な計算を、値を個別にテストする計算に置き換えるのは役に立たず-1
、ほとんどのリリース環境では、コア ライブラリが期待どおりに動作することを確認するテストをコードに散らかすことは不合理です。この場合、アサートは理想的です。