web-dev-qa-db-ja.com

JUnitメッセージは成功または失敗の状態を示す必要がありますか?

アサーションメッセージは、2つの方法のいずれかで作成できます。成功を述べる:

assertEquals( "objects should be identical", expected, actual );

または壊れている状態を述べる:

assertEquals( "objects aren't identical", expected, actual );

JUnitには特にこれに関する標準がありますか?そうでない場合、各側の引数は何ですか?

追伸私はこれらの両方を説明せずに示すウェブ上の記事を見たので、「Googleを検索する」と言っても答えにはなりません!

[UPDATE]

私がassertEqualsを使用したという事実に誰もが夢中になっているので、メッセージはおそらく役に立たないでしょう。しかし、もちろん、それは単に質問を簡単に説明したかったからです。

だから代わりにそれを想像してください:

assertTrue( ... big long multi-line expression ... );

メッセージが役立つ場所。

61
Jason Cohen

少なくともassertEqualsについては、私はめったにメッセージを気にしません。賢明なテストランナーは、あなたがassertEqualsを使用していたことと、2つの等しいことを意図していたことを説明します。どちらのメッセージもそれ以上の情報を提供しません。

通常、ユニットテストの失敗は一時的なものであることがわかります。何が間違っているかをすばやく見つけて修正します。 「何が問題なのかを見つける」には、通常、1つのメッセージで大きな違いが生じないほど十分な詳細が含まれます。 「メッセージを持つことで節約できる時間」と「メッセージを考えるのに費やした時間」を考慮してください:)

編集:さて、私はmightメッセージを使用する1つのケース:オブジェクトの文字列表現からはわからないテキストに簡潔な説明がある場合。

例:ミリ秒として保存された日付を比較する場合の「12月1日になる予定の日付」。

しかし、あなたがそれをどのように正確に表現するかについて心配することはありません:それがあなたの意味するメッセージから明白であることを確かめてください。 「あるべき」または「なかった」のどちらでも構いません-「12月1日」だけでは明らかではありません。

30
Jon Skeet

Junit APIによると、メッセージは「AssertionErrorの識別メッセージ」であるため、満たすべき条件を説明するメッセージではなく、条件が満たされない場合の問題点を説明するメッセージです。したがって、あなたの例では、「オブジェクトは同一ではありません」はより適合しているようです。

22
Reto Gmür

他の多くの人とは異なり、メッセージを使用することは多くの理由で非常に役立つと感じています。

  1. 失敗したテストのログを見ている人は、テストを書いた人ではないかもしれません。コードを読み、アサーションが対処すべきケースを理解するには時間がかかる場合があります。役立つメッセージは時間を節約します。

  2. ログを見るのはテストの開発者である場合でも、テストが記述されてから数日または数か月である可能性があります。また、メッセージにより時間を節約できます。

私のアドバイスは、予想される動作のステートメントを使用してメッセージを書くことです。例えば:

assertEquals("The method should be invoked 3 times", 3, invocationCount);
9
Matt Accola

私はそれがまったく重要だとは思わない-あなたはすでに障害が起こったことを知っているので、メッセージが何が起こったのか、何が起こってはならないのかを述べているかどうかは関係ない。

メッセージの目標は、できる限り支援することであり、完全性を確保することではありません。

明らかに、assertEqualsの場合、これはそれほど重要ではありませんが、一般的なアサートの場合、メッセージは重要です。このメッセージは、正確に何が失敗したかをすぐに理解するのに十分なコンテキストを取得するのに役立ちます。

ただし、必要なコンテキストの量(およびメッセージの詳細)は、レポートの取得方法によって異なります。たとえば、Eclipseで取得した場合、簡単に行って対話し、何が起こったのかを確認できるため、メッセージはそれほど重要ではありません。ただし、レポートを(連続ビルドサーバーなどから)電子メールで送信する場合は、対応するソースコードに移動する前に何が起こっているかを把握できるように、メッセージに十分な情報を提供する必要があります。

3
Uri

Generelのメッセージが役立つかどうかを考慮せずに質問に答えたいと思います。

テストが失敗した場合、何かが間違っています。私はこれを知っている。なぜ壊れているのか知りたい。テストケースとSUTを開くだけなので、見つけるのは非常に簡単です。ジョンが言ったように、それを修正するのは非常に簡単です(できれば;-))。

しかし、メッセージはどうですか?このメッセージは私にとってアドバイスであり、それを環境に優しいテストケースに変えるために何ができるかです。そのため、メッセージテキストにアドバイスがあれば、この問題の修正方法や問題の検索場所を教えてください。

別の興味深い側面は、肯定的な表現の使用です。肯定的なテキストメッセージを使用することを検討する価値があります。あなたの例では、Objects should be identicalを使用します。しかし、それは小さな理由です。

3
guerda

仕様によると、メッセージはエラーが発生したときのエラーを説明するものです。 JenkinsなどのCI環境でアプリケーションを構築し、プラグインを使用してエラー結果を分析する場合に役立ちます。

http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertTrue(Java.lang.String、%20boolean)

message-AssertionErrorの識別メッセージ(null OK)

2
Wander Costa

この質問は2つの観点から見ています。

最初の、そして最も一般的な視点は、ここで私たちのほとんどがすでに議論しています:ログを見てエラーを修正しようとしている人の視点から:私は両方のメッセージが等しく提供すると信じています情報。

2番目の視点は、コードを読んだり、保守したり、レビューしたりする人の視点ですコードの読みやすさとシンプルさについて古くから話してきました。したがって、それも同様に重要です。

私たちは、明示的なコメントが不要であり、強く同意するように、私のコードはシンプルで自明であるべきだと信じさせられました。

この観点から:

これらのメッセージは、ドキュメントとエラー報告の2つの目的を果たすため、コードを読みやすくするのがはるかに簡単になります。

assertEquals( "objects should be identical", expected, actual );
assertTrue( "flag should have been set", flag );
assertNotNull( "object must not be null", object );

これらのメッセージは、予想外の状態について説明しているため、読者にはあまりわかりません。

assertEquals( "objects aren't identical", expected, actual );
assertTrue( "flag is not set", flag );
assertNotNull( "object is null", object );
2
Mohd Farid

私にも投票してください(Jonなど)が、このようなメッセージを(アサートに等しい)使用したことがあるのは、値のマトリックスを使用して単一のテストを構築し、テスト要素の1つが失敗したときだけです:メッセージを使用しますどのテストケースが失敗したかを示します。それ以外の場合、テキストは完全に冗長です。

1
James Hugard

JUnitのjavadocsから:

2つのオブジェクトが等しいことをアサートします。これらがAssertionFailedErrorでない場合、指定されたメッセージとともにスローされます。

APIによると、メッセージは何でも構いません。私はあなたが持っている2つのオプションは両方とも同じであり、両方とも余分であると主張します。アサートの成功または失敗は、メッセージで提供しているすべての情報をすでに提供しています。

私には、何も持たないはずです(意図的に文字列をとらないアサートがあります)ORすでに存在する以上の意味を持つメッセージを含めます。

だから、これはジョンの答えを繰り返したものだと思うが、コメントするには余りにも冗長だ。

1
Instantsoup

特に、Spockテストフレームワークがストーリーのように読み、同様に異なるフレームワークでテストを構築するようになったテストを奨励する方法が気に入っています。個々のエラーメッセージが意味をなすことについては特に心配していません。テストを開いたらすぐにテスト全体をすばやくラップすることを目指しています。

assertEquals("Cloned and persisted items", mockedTiCount, clonedTis.size());
assertTrue("Belong to new transaction", clonedTis.stream().allMatch(ti -> ti.getTransaction().getId().equals(cloned.getId())));
assertNotEquals("Which has a different ID", t.getId(), cloned.getId());
assertEquals("While the originals are left intact", mockedTiCount, transactionItemRepository.findByTransactionId(t.getId()).size());

いくつかの大きなテストの代わりに多くの小さなテストを選択することも、きちんと構造化された、再利用可能なテスト設定コードと同様に、ここで役立ちます。

0
Gregor Petrin

メッセージを提供することは有益であり、常に提供することに同意します。

私にとって、含めるべき有益なことは、何が間違っていたかの明確な声明です。通常、「すべき」または「すべきではない」という言葉が含まれます。

たとえば、「オブジェクトが等しい」はあいまいです-オブジェクトが等しいことを意味し、それがテストが失敗した理由ですか?または、そのオブジェクトは等しいはずですが、そうではありませんか?しかし、「オブジェクトは等しくなければならない」または「オブジェクトは等しくないはずです」と言うと、アサーションが失敗した理由は明らかです。

0
sync

ループで実行している類似のテスト値の配列があるテストを実行しており、どれが失敗したかを正確に特定したい場合を除き、引用したケースにはメッセージを表示しません。次に、メッセージを追加して、どのメッセージかを通知します。

0
duffymo