質問
なぜ assert
キーワードがJavaであまり使用されていないのでしょうか?私はそれらが使用されるのを見たことがほとんどありませんが、それらは素晴らしいアイデアだと思います。私は確かに以下の簡潔さを好む:
assert param != null : "Param cannot be null";
の冗長性:
if (param == null) {
throw new IllegalArgumentException("Param cannot be null");
}
私の疑いは、それらが十分に活用されていないことです
- 彼らは比較的遅れて到着し(Java 1.4)、その頃には多くの人々がすでにJavaプログラミングスタイル/習慣を確立していた
- これらは実行時にデフォルトでオフになります
解決
アサーションは、理論的には、不変式、コードが適切に完了するためには、必須であるという前提。
示されている例は、有効な入力のテストです。これは、一般にユーザーが提供するため、アサーションの一般的な使用法ではありません。
アサーションは、オーバーヘッドがあり、開発およびテスト中に不変式が失敗する状況がコーディングエラーとしてキャッチされたと想定されるため、一般に実稼働コードでは使用されません。
「遅れて」来ることについてのあなたのポイントまた、Javaがより広く見られない理由でもあります。
また、単体テストフレームワークでは、テスト対象のコードの外部にプログラムアサーションが必要になる場合があります。
他のヒント
アサーションを使用してユーザー入力をテストするのはアサーションの乱用です。無効な入力で IllegalArgumentException
をスローすると、呼び出し元のメソッドが例外をキャッチし、エラーを表示し、必要なことを何でも行うことができるため、より正確です。 / p>
そのメソッドがクラス内のプライベートメソッドである場合、アサーションは問題ありません。誤ってnull引数を渡さないようにするためです。アサーションをオンにしてテストし、アサーションをトリガーしないですべてのパスをテストしたら、リソースを無駄にしないようにアサーションをオフにできます。コメントとしても便利です。メソッドの開始時の assert
は、特定の前提条件に従うべきであるというメンテナーへの優れたドキュメントであり、最後の assert
はメソッドのあるべき姿をドキュメント化したものです。やっています。コメントと同じくらい便利です。さらに、アサーションをオンにすると、文書化された内容を実際にテストするためです。
アサーションはテスト/デバッグ用であり、エラーチェックではありません。そのため、デフォルトではオフになっています。つまり、ユーザー入力を検証するためにアサーションを使用しないようにします。
デフォルトでは、実行時にアサーションは無効になっています。 2つのコマンドラインスイッチを使用すると、アサーションを選択的に有効または無効にできます。
これは、ランタイム環境を完全に制御できない場合、アサーションコードが呼び出されることを保証できないことを意味します。アサーションは、実稼働コードではなく、テスト環境で使用することを目的としています。ユーザーがアサーションを無効にしてアプリケーションを実行すると( default )、エラー処理コードがすべて消えるため、例外処理をアサーションに置き換えることはできません。
" Effective Java"で、Joshua Blochは("パラメーターの有効性を確認する"トピックで)提案しました(採用する単純なルールのようなもの)、パブリックメソッドの場合、引数を検証し、必要な例外をスローします無効であることが判明した場合、および非公開メソッド(公開されておらず、そのユーザーとしての有効性を確認する必要があります)の場合、代わりにアサーションを使用できます。
yc
@Don、アサーションがデフォルトでオフになっていることに不満を感じています。私もそうだったので、インライン化する小さなjavacプラグインを作成しました(つまり、この愚かなアサートバイトコードではなく、 if(!expr)throw Ex
のバイトコードを出力します。
Javaコードのコンパイル中にクラスパスに fa.jar を含めると、魔法をかけた後、教えます
Note: %n assertions inlined.
@see http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions またはgithub https://github.com/akuhn/javac
アサートを記述してから標準のif then条件ステートメントに置き換える理由がわからないのですが、最初にifのように条件を記述するだけではどうですか?
アサートはテスト専用であり、2つの副次効果があります。有効にすると、バイナリが大きくなり、パフォーマンスが低下します(これを無効にできる理由です)
アサーションは条件の検証に使用しないでください。アサーションを有効/無効にすると実行時にアプリの動作が異なるため、悪夢です!
アサーションは次の理由で便利です:
- プログラミングエラーを早期に検出
- コードを使用したドキュメントコード
それらをコードの自己検証と考えてください。失敗した場合は、プログラムが壊れており、停止する必要があることを意味するはずです。単体テスト中は常に有効にしてください!
プラグマティックプログラマでは、本番環境で実行することを推奨しています。
アサーションを有効のままにする
アサーションを使用して不可能を防ぐ。
アサーションが失敗するとAssertionErrorがスローされるため、catch Exceptionでキャッチされないことに注意してください。
アサーションは非常に制限されています。ブール条件のみをテストでき、毎回有用なエラーメッセージのコードを記述する必要があります。これをJUnitのassertEquals()と比較して、入力から有用なエラーメッセージを生成し、JUnitランナーのIDEで2つの入力を並べて表示することもできます。
また、これまで見てきたどのIDEでもアサーションを検索することはできませんが、すべてのIDEはメソッド呼び出しを検索できます。
実際には、Java 1.4で到着しました
主な問題は、EclipseまたはJ2EEサーバーのように自分で直接jvmオプションを管理しない環境でコーディングする場合(どちらの場合もjvmオプションを変更することは可能ですが、深く検索する必要があることです)どこで実行できるかを見つける)、ifと例外を使用する(または何も使用しないのが悪い)方が簡単です(つまり、労力が少なくなります)。
他の人が述べているように、アサーションはユーザー入力の検証には適切ではありません。
冗長性に関心がある場合は、私が書いたライブラリをチェックアウトすることをお勧めします。 https:// bitbucket .org / cowwoc / requirements / 。ごくわずかなコードを使用してこれらのチェックを表現できるようになり、ユーザーに代わってエラーメッセージを生成することもできます。
requireThat("name", value).isNotNull();
そしてアサーションの使用を主張する場合、これも行うことができます:
assertThat("name", value).isNotNull();
出力は次のようになります。
java.lang.NullPointerException: name may not be null
tl; dr
このページの他の回答のほとんどは、「アサーションは本番コードでは通常使用されません」という格言を押しています。ワードプロセッサやスプレッドシートなどの生産性アプリには当てはまりますが、Javaが一般的に使用されるカスタムビジネスアプリでは、実稼働環境でのアサーションテストは非常に便利で一般的です。
プログラミングの世界の多くの格言のように、あるコンテキストで真であることが間違って解釈され、次に他のコンテキストで誤って適用されます。
生産性アプリ
「アサーションは本番コードでは通常使用されません」というこの格言は、一般的ですが、正しくありません。
形式化されたアサーションテストは、 Microsoft Word などのワードプロセッサなどのアプリに由来します。 Microsoft Excel のようなスプレッドシート。これらのアプリは、ユーザーが行ったすべてのキーストロークでアサーションテストアサーションの配列を呼び出す可能性があります。このような極端な繰り返しは、パフォーマンスに深刻な影響を与えました。したがって、限定配布のこのような製品のベータ版のみがアサーションを有効にしました。したがって、格言。
ビジネスアプリ
対照的に、データ入力、データベース、またはその他のデータ処理用のビジネス指向アプリでは、実稼働環境でのアサーションテストの使用は非常に便利です。パフォーマンスへのわずかなヒットにより、非常に実用的になります–そして共通。
ビジネスルールをテストする
実稼働環境での実行時のビジネスルールの検証は完全に合理的であり、推奨されるべきです。たとえば、請求書に常に1つ以上の広告申込情報が必要な場合は、請求書の広告申込情報の数がゼロより大きいことを確認するアサーションテストを記述します。製品名が少なくとも3文字以上である必要がある場合は、文字列の長さをテストするアサーションを記述します。このようなテストは、本番環境のパフォーマンスに大きな影響を与えません。
ランタイム条件
アプリが実稼働環境で実行されているときに特定の条件が常に真であると予想する場合、アサーションテストとしてそれらの期待をコードに記述します。
これらの条件が適度に失敗することが予想される場合は、アサーションテストを書きません。おそらく特定の例外をスローします。その後、可能な限り回復を試みます。
健全性チェック
実稼働環境での実行時の健全性チェックも完全に合理的であり、推奨されるべきです。 。真実ではないと想像できないいくつかのarbitrary意的な条件をテストすることで、奇妙な出来事が起こった無数の状況で私のベーコンを救いました。
たとえば、ニッケル(0.05)をペニーに丸めると、特定のライブラリでニッケル(0.05)になるというテストは、Appleが出荷した浮動小数点技術の欠陥を発見した最初の人の1人になったPowerPCからIntelへの移行中の Rosetta ライブラリ。そのような欠陥が一般に広まることは不可能に思えたでしょう。しかし驚くべきことに、この欠陥は、元のベンダー、Transitive、Apple、およびAppleのベータ版でテストする早期アクセス開発者の通知を逃れていました。