断言(assert)和 JUnit 断言的区别

100

今天我看到一个JUnit测试用例中使用了Java断言而不是JUnit断言 - 优先选择其中一种是否有重大优势或劣势?

今天我看到一个JUnit测试用例中使用了Java断言而不是JUnit断言,想知道是否有明显的优缺点。

JUnit断言和Java的“assert”关键字之间存在明显的事实差异。这绝不是基于观点的问题。 - Thomas W
6个回答

107
在JUnit4中,由JUnit断言引发的异常(实际上是错误)与Java assert 关键字引发的错误(AssertionError)相同,因此与assertTrue 完全相同,除了堆栈跟踪之外,您无法区分它们。
话虽如此,断言必须在JVM中以特殊标志运行,导致许多测试似乎通过,只是因为当运行JUnit测试时某人忘记配置该标志-这不太好。
一般来说,因为这个原因,我认为使用JUnit assertTrue 是更好的实践,因为它保证测试被运行,确保一致性(有时会使用 assertThat 或其他不是java关键字的断言),如果JUnit断言的行为在将来发生改变(例如连接到某种过滤器或其他未来的JUnit功能),您的代码将能够利用它。
Java中断言关键字的真正目的是能够在没有运行时惩罚的情况下关闭它。但这并不适用于单元测试。

28

我更喜欢使用JUnit断言,因为它们提供了比内置的assert语句更丰富的API,并且更重要的是不需要显式启用,而assert则需要-ea JVM参数。


1
在“mvn test”中,“-ea”始终启用,无需使用“-ea”。更丰富的API,更好的捕获。有时我认为在测试中滥用了API,因为它不是应用程序的一部分(API中的“a”),我更喜欢将其称为更丰富的方法。 - Grim

23

当测试失败时,您会获得更多信息。

assertEquals(1, 2); 的结果是 java.lang.AssertionError: expected:<1> but was:<2>

相比之下,

assert(1 == 2); 的结果是 java.lang.AssertionError

如果您向 assertEquals 添加消息参数,您可以获得更多信息。


10
请尝试使用assert 1==2: "1不等于2"; - Grim
1
@ThomasW 当-ea未启用时,它不是一个测试。JUnit断言并不总是有效,只有在您决定使用JUnit作为框架时才有效,并且在maven的情况下,必须是test-scope的maven依赖项。我们有两个选择:第一种选择:使用一个框架,作为test-scope的依赖项,必须下载,Eclipse可以让您在不在src/main文件夹中的类中使用它,但无法编译,因为Maven仅在test-scope中具有JUnit或第二种选择:使用内置的东西。 - Grim
1
@PeterRader 这个问题是关于JUnit测试用例的。在这种情况下,应该使用JUnit或类似的断言类,因为它们始终处于启用状态。我个人曾经因Java中的“assert”关键字未启用而遇到过问题,并且不认为不可靠的断言在测试代码中有任何作用。 - Thomas W
在特性代码中的断言的独立上下文中--这是健壮编程实践的重要部分,虽然不是问题的主题--Spring和Google Guava都有始终启用的断言类。我建议慷慨地使用这些作为参数和状态前提条件以确保正确性。除此之外,在性能关键的领域,可能存在一小部分情况,其中Javaassert可能更可取--对于会影响性能并且最好默认禁用的正确性检查。然而,我的经验是大多数断言应该始终开启。 - Thomas W
虽然这样说有点不礼貌,但既然他同意这不是反模式,那就不是个人攻击。 - Grim
显示剩余3条评论

8

我建议在测试用例中使用JUnit断言,而在代码中使用Java的assert。换句话说,真正的代码不应该依赖于JUnit,这是显而易见的,如果是测试代码,则应使用JUnit的变体,而不是assert。


0
我认为如果你正在使用JUnit,你应该使用JUnit的断言。`assertTrue()`基本上与`assert`相同,否则为什么要使用JUnit呢?

4
您可以使用JUnit作为测试运行框架。断言只是JUnit提供的价值的一小部分。如果没有Assert,JUnit需要编写更多样板代码。如果没有JUnit,使用assert将需要您编写整个框架。 - Yishai
1
我更多的是在说,如果你要使用这个工具,就要好好地用它。在 JUnit 测试用例中,普通的 assert 语句似乎有点傻。在我看来,它们应该与实际代码放在一起。 - CheesePls
1
@CheesePls "常规的assert语句"实际上比JUnit asserts更加近期。 - dolmen

0

如果您仅使用新的、闪亮的东西,那么这可能并不适用,但是assert在Java 1.4SE之前并不存在。因此,如果您必须在旧技术环境下工作,出于兼容性考虑,您可以倾向于使用JUnit。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接