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

时间:2009-07-02 15:05:07

标签: java unit-testing junit

我可以用两种方式之一编写断言消息。陈述成功:

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

或说明被打破的情况:

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

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

P.S。我在网上看过这些文章,但没有解释,只是说“搜索Google”不是答案!

[UPDATE]

每个人都对我使用assertEquals的事实感到困惑,因此这条消息可能毫无用处。但当然这仅仅是因为我想简单地说明这个问题。

所以想象一下:

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

消息有用。

12 个答案:

答案 0 :(得分:30)

我甚至很少打扰消息,至少对assertEquals而言。任何明智的测试运行员都会解释你使用的是assertEquals以及两个本来是平等的东西。您的消息都没有提供更多信息。

我经常发现单元测试失败是暂时的 - 我会很快找出错误并修复它。 “发现什么是错的”通常涉及足够的细节,单个消息不会产生太大的影响。考虑“通过消息节省时间”与“花在思考消息上的时间”:)

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

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

我不会担心你如何准确地表达它:只是确保从你的意思是明确的消息。 “应该是”或“不是”是好的 - 只是“12月1日”不会很明显。

答案 1 :(得分:22)

根据junit API,消息是“AssertionError的标识消息”,因此它不是描述应该满足的条件的消息,而是描述如果不满足条件则出错的消息。因此,在您的示例中,“对象不相同”似乎更符合要求。

答案 2 :(得分:9)

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

  1. 查看测试失败日志的人可能不是编写测试的人。阅读代码并了解断言要解决的案例需要花费一些时间。有用的信息可以节省时间。

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

    < / LI>

    我的建议是写一条消息,说明预期的行为。例如:

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

答案 3 :(得分:3)

我认为这根本不重要 - 你已经知道发生了失败,因此如果消息说明应该发生什么,或者什么不应该发生,那也没关系。

信息的目标是尽可能地帮助你,而不是获得一些完整性。

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

但是,所需的上下文量(以及消息中的详细信息)应取决于您获取报告的方式。例如,如果您在Eclipse中获得它,您可以轻松地进行交互并查看发生的情况,因此消息不那么重要。但是,如果您通过电子邮件向您发送报告(例如,从连续构建服务器),那么您希望该消息提供足够的信息,以便您在了解相应的源代码之前了解正在发生的事情。

答案 4 :(得分:3)

我想在不考虑的情况下回答这个问题,如果genrel中的消息有用。

如果测试失败,则出现问题。我知道这个。我想知道为什么它被打破了。这很容易找到,因为我只需要打开测试用例和SUT。 就像Jon说的那样,很容易解决它(希望;-))。

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

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

答案 5 :(得分:2)

根据规范,消息是在错误发生时描述错误。 当您在CI环境(如Jenkins)中构建应用程序并使用插件分析错误结果时,它非常有用。

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

  

message - AssertionError的标识消息(null okay)

答案 6 :(得分:1)

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

答案 7 :(得分:1)

来自JUnit的javadoc:

  

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

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

对我来说,你应该什么都没有(有一个断言不会故意接受一个字符串)或者包含一个超出已经存在的含义的消息。

所以我想这是对Jon的回答的重复,但是过于冗长无法发表评论。

答案 8 :(得分:0)

我没有给你引用的案例留言,除非我正在运行一个测试,我有一个类似的测试值数组,我正在循环运行,我想确切地指出哪一个失败了。然后我添加一条消息告诉我哪一个。

答案 9 :(得分:0)

我同意提供信息很有帮助,我总是提供一条信息。

对我而言,要包含的有用之处在于明确说明出了什么问题 - 通常涉及“应该&#39;或者&#39;不应该&#39;。

,例如&#34;对象是平等的#34;是不明确的 - 它是否意味着对象是平等的,这是测试失败的原因?或者那些对象应该是平等的,但它们不是吗?但如果你说&#34;对象应该是平等的#34;或&#34;对象不应该相等&#34;断言失败的原因显而易见。

答案 10 :(得分:0)

我特别喜欢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());

选择许​​多小测试而不是几个大测试也有帮助,就像一个结构整齐,希望可重复使用的测试设置代码一样。

答案 11 :(得分:0)

当测试失败时,这些消息特别重要。当失败时,您不仅要知道对象应该是相等的,还想知道为什么应该相等。

所以不是

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

使用

assertEquals( "Status code should be 403 (forbidden), because a user "     
+ "with role customer must not be allowed to access the admin console.", 
403, statusCode );

是的,允许消息很长,只要它们可以帮助开发人员快速识别问题并以正确的方式解决它。