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