アサーションを使用する手法についてもう少し説明したいと思います。
アサーションを使用すると、コード内の任意の時点で真であると予想される内容を指定できます。関数の開始時に、アサーションを使用して、パラメーターに適切な値があることを確認できます。これらは前提条件と呼ばれます。そして、関数の終わりに、返そうとしているものが関数の目的と一致していることを確認することができます。これらは事後条件と呼ばれます。関数の途中で、中間計算が妥当であることを確認できます(ただし、通常、関数を十分に小さくして、中間計算が多くないようにする必要があります)。
クラスを使用すると、適切な値がコンストラクターに渡されていることを確認できます。他のメソッドでは、メソッドが戻る前に、クラスの一般的な状態が適切であることを確認できます。これらは不変量と呼ばれます。
私がデバッグしているとき、私は通常、いくつかのアサーションを見逃し、クラッシュを問題の原因から遠ざけるため、バグを見つけるのが難しいことに気付きます。私はそれを修正するためにデバッグプロセスを使用します。クラッシュが実際に発生した場所から始めて、「このレベルの抽象化では、何が問題だったのか」と考えます。関数の途中でクラッシュした場合は、関数に渡されたパラメーターが正しくないことに気付く可能性があるため、関数の先頭近くにアサーションを追加して、それらをキャッチします。次回実行してクラッシュすると、クラッシュはもう少し早く発生します。関数の最上位でクラッシュが発生した場合は、スタックの1レベル上に移動して、「呼び出し元が正しい値を渡さなかったのはなぜですか?」と尋ねます。そうすると、中間計算が間違っていたことに気付くかもしれません。そこで、アサーションを追加して、それを早期にキャッチします。中間計算は、別の関数が間違った値を返したことが原因である可能性があります。その場合は、事後条件アサーションを追加して、それを先にキャッチします。現在の関数に適切なパラメーターが渡されていないことが原因である可能性があるため、この関数に前提条件アサーションを追加します。
アサーションを追加するたびに、問題の実際の原因の近くでクラッシュが発生します。最終的には、実際のロジックエラーでクラッシュが発生するようになり、修正は明らかです。しかし、このプロセスを経ることで、将来の問題を見つけやすくなる可能性も高くなりました。
単体テストを行うときに、同様の推論を適用できます。「この問題を早期に発見できなかった私のテストの何が問題だったのか」と尋ねます。