tl;dr
- はい、意味のある本番環境でアサーション テストを使用します。
- 必要に応じて、組み込み機能ではなく、他のライブラリ ( JUnit、AssertJ、Hamcrest
assert
など) を使用してください。
このページの他の回答のほとんどは、「アサーションは通常、運用コードでは使用されません」という格言を押し付けています。ワープロやスプレッドシートなどの生産性アプリでは当てはまりますが、Java が非常に一般的に使用されるカスタム ビジネス アプリでは、アサーション-本番環境でのテストは非常に便利であり、一般的です。
プログラミングの世界の多くの格言と同様に、ある文脈では正しいと思われることは、誤解され、別の文脈では誤って適用されます。
生産性アプリ
「アサーションは通常、製品コードでは使用されない」というこの格言は、一般的ではありますが、正しくありません。
形式化されたアサーション テストは、 Microsoft WordなどのワードプロセッサやMicrosoft Excelなどのスプレッドシートなどのアプリで生まれました。これらのアプリは、ユーザーがキーストロークを行うたびに一連のアサーション テスト アサーションを呼び出す可能性があります。このような極端な繰り返しは、パフォーマンスに深刻な影響を与えました。そのため、配布が制限されているそのような製品のベータ版のみがアサーションを有効にしていました。したがって、格言。
ビジネスアプリ
対照的に、データ入力、データベース、またはその他のデータ処理用のビジネス指向アプリでは、本番環境でのアサーション テストの使用は非常に役立ちます。パフォーマンスへのわずかな影響により、非常に実用的で一般的なものになります.
ビジネス ルールのテスト
本番環境での実行時にビジネス ルールを検証することは完全に合理的であり、推奨されます。例えば:
- 請求書に常に 1 つ以上の項目が必要な場合は、請求書の項目の数が 0 より大きいかどうかをテストするアサーションを記述します。
- 製品名が少なくとも 3 文字以上でなければならない場合は、文字列の長さをテストするアサーションを記述します。
- 現金元帳の残高を計算するとき、結果が決して負になることはあり得ないことがわかっているので、データまたはコードの欠陥を示す負の数をチェックしてください。
このようなテストは、本番環境のパフォーマンスに大きな影響を与えません。
実行条件
アプリが本番環境で実行されるときに、特定の条件が常に真であることをアプリが想定している場合は、それらの想定をアサーション テストとしてコードに記述します。
これらの条件がときどき失敗する可能性があると予想される場合は、アサーション テストを記述しないでください。おそらく、特定の例外をスローします。その後、可能な限り回復を試みます。
健全性チェック
本番環境での実行時の健全性チェックも完全に合理的であり、推奨されるべきです。真実でないとは想像もつかないいくつかの恣意的な条件をテストすることで、奇妙な出来事が発生した数え切れないほどの状況でベーコンを救うことができました。
たとえば、特定のライブラリでニッケル (0.05) をペニーに丸めるとニッケル (0.05) になることをテストしたことで、Apple がRosettaライブラリに出荷した浮動小数点技術の欠陥を最初に発見した人の 1 人になりました。 PowerPC から Intel への移行。そのような欠陥が一般に届くことは不可能に思えたでしょう。しかし驚くべきことに、この脆弱性は、元のベンダーである Transitive と Apple、そして Apple のベータ版でテストを行っていた早期アクセスの開発者の目に留まることはありませんでした。
(ちなみに、私は言及する必要があります…お金のために浮動小数点を使用しないでください、使用してBigDecimal
ください。)
フレームワークの選択
組み込み機能を使用するのではなく、assert
別のアサーション フレームワークの使用を検討することをお勧めします。次のような複数のオプションがあります。
または独自のロール。プロジェクトで使用する小さなクラスを作成します。このようなもの。
package work.basil.example;
public class Assertions {
static public void assertTrue ( Boolean booleanExpression , CharSequence message ) throws java.lang.AssertionError {
if ( booleanExpression ) {
// No code needed here.
} else { // If booleanExpression is false rather than expected true, throw assertion error.
// FIXME: Add logging.
throw new java.lang.AssertionError( message.toString() );
}
}
}
使用例:
Assertions.assertTrue(
localTime.isBefore( LocalTime.NOON ) ,
"The time-of-day is too late, after noon: " + localTime + ". Message # 816a2a26-2b95-45fa-9b0a-5d10884d819d."
) ;
あなたの質問
それらが登場したのは比較的遅く (Java 1.4)、その頃には多くの人が Java プログラミングのスタイルや習慣をすでに確立していました。
はい、これは本当です。多くの人々は、Sun/JCP がアサーション テスト用に開発した API に失望しました。そのデザインは、既存のライブラリに比べて精彩を欠いていました。非常に多くの人が新しい API を無視し、既知のツール (サードパーティ ツール、または独自のミニ ライブラリを作成) を使い続けました。
これらはデフォルトで実行時にオフになっています.WHY OH WHY??
初期の頃、Java はパフォーマンス速度の低さで非難されていました。皮肉なことに、Java は急速に進化し、最高のパフォーマンス プラットフォームの 1 つになりました。しかし、悪いラップは臭い匂いのようにぶら下がっていました。そのため、Sun は、測定可能な方法でパフォーマンスに影響を与える可能性のあるものには、非常に慎重でした。したがって、この観点から、アサーション テストを無効にすることをデフォルトにすることは理にかなっています。
デフォルトで無効にするもう 1 つの理由は、新しいアサーション機能を追加する際に、Sun が単語をハイジャックしたという事実に関連していた可能性がありますassert
。これは、以前は予約されていたキーワードではなく、Java 言語に加えられた数少ない変更の 1 つが必要でした。メソッド名assert
は、多くのライブラリや多くの開発者が独自のコードで使用していました。この歴史的な移行に関する議論については、この古いドキュメント、Programming With Assertionsをお読みください。