Java JUnit 消息是否应该说明成功或失败的条件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1074928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:12:47  来源:igfitidea点击:

Should the JUnit message state the condition of success or failure?

javaunit-testingjunit

提问by Jason Cohen

I can write an assertion message one of two ways. Stating success:

我可以通过两种方式之一编写断言消息。说明成功:

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

Or stating the condition of being broken:

或说明被破坏的条件:

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

Is there a standard for this in JUnit specifically? If not, what are the arguments for each side?

JUnit 中有专门的标准吗?如果不是,每一方的论据是什么?

P.S. I've seen articles on the web demonstrating both of these without explanation, so just saying "search Google" is not an answer!

PS 我已经在网上看到文章没有解释地展示了这两个,所以只说“搜索谷歌”不是答案!

[UPDATE]

[更新]

Everyone is getting hung up on the fact that I used assertEqualsand therefore the message is probably useless. But of course that's just because I wanted to illustrate the question simply.

每个人都被我使用过的事实所困扰assertEquals,因此该消息可能毫无用处。但当然这只是因为我想简单地说明这个问题。

So imagine instead it's:

所以想象一下,它是:

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

Where a message is useful.

消息有用的地方。

采纳答案by Jon Skeet

I rarely even bother with a message, at least for assertEquals. Any sensible test runner will explain that you were using assertEqualsand the two things which were meant to be equal. Neither of your messages give more information than that.

我什至很少打扰消息,至少对于assertEquals. 任何明智的测试运行器都会解释你正在使用assertEquals的两个东西是平等的。您的两条消息都没有提供更多信息。

I usually find that unit test failures are transient things - I'll rapidly find out what's wrong and fix it. The "finding out what's wrong" usually involves enough detail that a single message isn't going to make much difference. Consider "time saved by having a message" vs "time spent thinking of messages" :)

我通常发现单元测试失败是暂时的——我会迅速找出问题所在并修复它。“找出问题所在”通常涉及足够的细节,以至于一条消息不会产生太大影响。考虑“通过发送消息节省的时间”与“花在思考消息上的时间”:)

EDIT: Okay, one case where I mightuse a message: when there's a compact description in text which isn't obvious from the string representation of the object.

编辑:好的,我可能会使用一条消息的一种情况:当文本中有一个紧凑的描述时,从对象的字符串表示中并不明显。

For example: "Expected date to be December 1st" when comparing dates stored as milliseconds.

例如:“预期日期为 12 月 1 日”比较存储为毫秒的日期时。

I wouldn't worry about how you express it exactly though: just make sure it's obvious from the message which way you mean. Either "should be" or "wasn't" is fine - just "December 1st" wouldn't be obvious.

不过,我不会担心您如何准确表达它:只需确保从消息中可以明显看出您的意思。“应该是”或“不是”都可以——只是“12 月 1 日”不会很明显。

回答by Uri

I don't think it matters at all - You already know that a failure happened, and therefore it doesn't matter if the message states what should have happened, or what shouldn't happen.

我认为这根本不重要 - 您已经知道发生了故障,因此消息是否说明应该发生什么或不应该发生什么并不重要。

The goal of the message is to help you when it can, not to obtain some completeness.

该消息的目标是在可能的情况下帮助您,而不是获得某种完整性。

Obviously, in the case of assertEquals this is less important, but the message is important in the case of general asserts. The message should help you obtain enough context to understand right away what exactly failed.

显然,在 assertEquals 的情况下,这不太重要,但在一般断言的情况下,消息很重要。该消息应帮助您获得足够的上下文以立即了解究竟是什么失败了。

However, the amount of needed context (and thus the details in the message) should depend on how you get the report. For example, if you get it in Eclipse, you can easily go and interact and see what happened, so the message is less imporrtant. However, if you get your reports emailed to you (e.g., from a continuous build server) then you want the message to provide enough information so that you will have an idea of what is going on before you even go to the corresponding source code.

但是,所需上下文的数量(以及消息中的详细信息)应取决于您如何获得报告。例如,如果您在 Eclipse 中获得它,您可以轻松地去交互并查看发生了什么,因此消息就不那么重要了。但是,如果您的报告通过电子邮件发送给您(例如,来自持续构建服务器),那么您希望该消息提供足够的信息,以便您在访问相应的源代码之前就知道发生了什么。

回答by James Hugard

Vote me down too (like Jon), but the only time I've ever use a message like this (on assert equals) is when building a single test with a matrix of values and one of the test elements fails: I use the message to indicate which test case failed. Otherwise, the text is totally redundant.

也给我投票(比如 Jon),但我唯一一次使用这样的消息(在 assert equals 上)是在使用值矩阵构建单个测试并且其中一个测试元素失败时:我使用消息指示哪个测试用例失败。否则,文本完全是多余的。

回答by Instantsoup

From the javadocs of JUnit:

来自 JUnit 的 javadocs:

Asserts that two objects are equal. If they are not an AssertionFailedError is thrown with the given message.

断言两个对象相等。如果它们不是 AssertionFailedError 则抛出给定的消息。

According to the API, the message can be whatever you want. I would argue that the two options you have are both the same and both superfluous. The success or failure of the assert already provides all the information you are providing in the message.

根据 API,消息可以是您想要的任何内容。我认为您拥有的两个选项都是相同的,而且都是多余的。断言的成功或失败已经提供了您在消息中提供的所有信息。

It follows for me that you should have either nothing (there is an assert that doesn't take a string on purpose) OR include a message with meaning beyond what is already there.

对我来说,您应该没有任何东西(有一个不故意使用字符串的断言)或包含一条意义超出现有内容的消息。

So I guess this is a reiteration of Jon's answer, but too verbose to be a comment.

所以我想这是对乔恩回答的重申,但过于冗长而不能发表评论。

回答by duffymo

I don't put a message for the case you cite, unless I'm running a test where I have an array of similar test values that I'm running in a loop and I want to pinpoint exactly which one failed. Then I add a message to tell me which one.

我不会为您引用的案例添加消息,除非我正在运行一个测试,其中我有一组类似的测试值在循环中运行,并且我想准确指出哪个失败了。然后我添加一条消息告诉我是哪一个。

回答by guerda

I would like to answer the question without considering, if a message in generel is useful.

我想不加考虑地回答这个问题,如果一般的消息有用。

If a test fails, something is wrong. I know this. I want to know why it is broken. That's very easy to find out because I just have to open the test case and the SUT. Like Jon said, it's very easy to fix it (hopefully ;-) ).

如果测试失败,则说明有问题。我知道这个。我想知道它为什么坏了。这很容易找到,因为我只需要打开测试用例和 SUT。就像 Jon 说的,修复它很容易(希望 ;-) )。

But what about the message? The message is for me an advice, what could be done to turn it into a green test case. So I would appreciate if there's an advice given in the message text, how to fix this problem or where to search for the problem.

但是消息呢?这条消息对我来说是一个建议,可以做些什么来把它变成一个绿色的测试用例。因此,如果消息文本中提供了建议、如何解决此问题或在哪里搜索问题,我将不胜感激。

Another interesting aspect would be the usage of positive expressions. It's worth a consideration to use positive text messages. In your example, I would use Objects should be identical. But that's a small reason.

另一个有趣的方面是积极表达的使用。值得考虑使用积极的短信。在您的示例中,我将使用Objects should be identical. 但这只是一个小原因。

回答by Matt Accola

Unlike many others I feel that using a message is extremely helpful for many reasons:

与许多其他人不同,我觉得使用消息非常有帮助,原因有很多:

  1. The person looking at the logs of a failed test may not be the person who wrote the test. It can take time to read through the code and understand what case the assertion is meant to address. A helpful message will save time.

  2. Even in the event it is the developer of the test who is looking at the logs it may have been days or months since the test was written and, again, a message can save time.

  1. 查看失败测试日志的人可能不是编写测试的人。通读代码并了解断言要解决的情况可能需要时间。有用的消息将节省时间。

  2. 即使是测试的开发人员正在查看日志,也可能是测试编写后的数天或数月,同样,一条消息可以节省时间。

My advice would be to write the message with a statement of the expected behavior. For example:

我的建议是编写带有预期行为声明的消息。例如:

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

回答by Reto Gmür

According to the junit API the message is the "the identifying message for the AssertionError" so its not a message describing the condition that should be met but a message describing what's wrong if the condition isn't met. So in your example "objects aren't identical" seems to be more conformant.

根据junit API,该消息是“AssertionError 的识别消息”,因此它不是描述应该满足的条件的消息,而是描述不满足条件时出现什么问题的消息。因此,在您的示例中,“对象不相同”似乎更符合要求。

回答by sync

I agree that providing a message is helpful and I always provide one.

我同意提供消息是有帮助的,我总是提供一个。

To me, the useful thing to include is a clear statement of what went wrong - usually involving the words 'should' or 'should not'.

对我来说,包含的有用的事情是明确说明出了什么问题——通常涉及“应该”或“不应该”这两个词。

E.g., "objects are equal" is ambiguous - does it mean the objects are equal and that's why the test failed? Or that objects should be equal but they aren't? But if you say "Objects should be equal" or "Objects should not be equal" it's obvious why the assertion failed.

例如,“对象相等”是不明确的——这是否意味着对象相等并且这就是测试失败的原因?或者对象应该相等但它们不是?但是,如果您说“对象应该相等”或“对象不应该相等”,那么断言失败的原因就很明显了。

回答by Mohd Farid

I see this question from two perspectives,

我从两个角度看这个问题,

First and the most common perspective, which is already being discussed by most of us here: From the perspective of someone who is seeing the logs and trying to fix the error:I believe that both the messages provides equal information.

第一个也是最常见的观点,我们大多数人已经在这里讨论过:从查看日志并试图修复错误的人的角度来看:我相信这两条消息提供了相同的信息。

Second perspective is that of someone who is reading/ maintaining/ reviewing the code:As we have been talking since ages about the readability and simplicity of code. So, it is also equally important as well.

第二个观点是正在阅读/维护/代码的人:正如我们很久以来一直在谈论代码的可读性和简单性。因此,它也同样重要。

We have been made to believe that my code should be simple and self explanatory so that no explicit comments are needed and I strongly agree with it.

我们已经相信我的代码应该是简单和不言自明的,这样就不需要明确的注释,我非常同意它。

From this perspective:

从这个角度来说:

These messages make it a lot easier to read and go through the code as they serve the dual purpose of documentation as well as error reporting:

这些消息使阅读和浏览代码变得更加容易,因为它们具有文档和错误报告的双重目的:

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

These messages are not so reader friendly as they talk about the unexpected condition:

这些消息对读者不太友好,因为它们谈论的是意外情况:

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