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

我可以用两种方式之一写一个断言信息。 成功说明:

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

或者说明被打破的状况:

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

在JUnit中是否有这样的标准? 如果不是,各方有什么争议?

PS我已经看到网上的文章展示这两个这些没有解释,所以只是说“search谷歌”不是一个答案!

[UPDATE]

每个人都挂上了我使用assertEquals的事实,因此这个消息可能是无用的。 当然,这只是因为我想简单地说明这个问题。

所以想象一下吧:

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

消息是有用的。

我甚至很less打扰一个消息,至less对于assertEquals 。 任何明智的testing运行者都会解释你正在使用assertEquals和两个意思相同的东西。 你的信息都没有提供更多的信息。

我通常会发现unit testing失败是暂时的,我会迅速发现错误并修复它。 “发现什么是错误的”通常涉及足够的细节,单个消息不会有太大的变化。 考虑“通过留言节省时间”vs“花费时间思考消息”:)

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

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

我不担心你是怎么expression的,只要确保你的意思是明确的。 要么“应该”或“不是”是好的 – 只是“十二月一号”不会很明显。

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

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

  1. 查看testing失败日志的人可能不是testing人员。 通过代码读取可能需要一些时间,并理解断言是为了解决什么情况。 有用的信息将节省时间。

  2. 即使在testing开发者正在查看日志的情况下,testing写入也可能需要几天或几个月的时间,而且再次,一条消息可以节省时间。

我的build议是写一个预期行为的陈述。 例如:

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

我根本不认为这很重要 – 你已经知道发生了一个失败,因此,如果这个消息指出应该发生什么或者什么不应该发生,那并不重要。

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

很显然,在assertEquals的情况下,这个重要性就不那么重要了,但是对于general asserts来说,这个信息是重要的。 该消息应该帮助您获得足够的上下文,以便立即了解究竟失败了什么。

但是,所需上下文的数量(以及消息中的细节)应取决于您如何获取报表。 例如,如果你在Eclipse中得到它,你可以轻松地去和互动,看看发生了什么,所以消息不那么重要。 但是,如果您通过电子邮件将您的报告发送给您(例如,从连续的构build服务器),那么您希望该消息提供足够的信息,以便在甚至转到相应的源代码之前就能知道发生了什么。

我想回答这个问题,而不考虑generel中的信息是否有用。

如果一个testing失败了,有些事情是错的。 我知道这个。 我想知道为什么它坏了。 这很容易find,因为我只需要打开testing用例和SUT。 像乔恩说的那样,修复它非常容易(希望是;-))。

但是这个消息呢? 这个信息对我来说是一个build议,可以做些什么来把它变成一个绿色的testing用例。 所以,如果有消息文本中给出的build议,如何解决这个问题或在哪里寻找问题,我将不胜感激。

另一个有趣的方面是积极expression的使用。 使用正面的文本消息是值得考虑的。 在你的例子中,我将使用Objects should be identical 。 但这是一个小原因。

也投了我(像乔恩),但唯一一次我曾经使用这样的消息(在断言等于)是build立一个单一的testingmatrix的值和一个testing元素失败:我使用消息指出哪个testing用例失败。 否则,文本是完全多余的。

从JUnit的javadoc:

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

根据API,消息可以是任何你想要的。 我会争辩说,你有两个选项是相同的,都是多余的。 断言的成功或失败已经提供了你在消息中提供的所有信息。

对于我来说,你应该没有任何东西(有一个断言不会故意串),或者包含一个超出已经存在的意义的消息。

所以我想这是对Jon的回答的一个重申,但是太冗长是一个评论。

我从两个angular度看待这个问题,

第一个也是最普遍的观点,这个观点已经在我们这里被大多数人讨论了: 从看到日志并试图修正错误的人的angular度来看:我相信这两个信息都提供了相同的信息。

第二个观点是正在阅读/维护/检查代码的人:正如我们一直在谈论代码的可读性和简单性。 所以,这也同样重要。

我们已经相信我的代码应该简单明了,不需要明确的评论,我非常同意。

从这个angular度来看:

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

 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 ); 

我没有给你引用的情况下的消息,除非我正在运行一个testing,我有一个类似的testing值的数组,我正在循环运行,我想确切地指出哪一个失败。 然后我添加一个信息告诉我哪一个。

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

对我来说,包括的有用的东西清楚地说明了什么是错误的 – 通常涉及“应该”或“不应该”这些词。

例如,“对象是平等的”是不明确的 – 这是否意味着对象是平等的,这就是为什么testing失败? 或者说对象应该是平等的,但不是? 但是如果你说“对象应该是平等的”或者“对象不应该是平等的”,那么显然为什么断言失败了。

我特别喜欢Spocktesting框架如何鼓励像一个故事一样阅读的testing,并且在不同框架下类似地构造testing。 我并不是特别在意个别的错误信息,因为我打开它的目的是快速地将我的头部包裹在整个testing中:

 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()); 

select许多小型testing,而不是几个大型testing,对于这里也是有帮助的,就像一个整洁的结构,希望可重用的testing设置代码一样。

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

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

 Parameters: message - the identifying message for the AssertionError (null okay) condition - condition to be checked