单元测试:在设置方法中有断言是一种好习惯吗?

Posted

技术标签:

【中文标题】单元测试:在设置方法中有断言是一种好习惯吗?【英文标题】:Unit testing: Is it a good practice to have assertions in setup methods? 【发布时间】:2010-11-25 05:01:42 【问题描述】:

在单元测试中,setup 方法用于创建测试所需的对象。

在这些设置方法中,我喜欢使用断言:我知道我想在这些方法中看到什么值 对象,我喜欢通过断言记录这些知识。

最近在 *** 上的 unit tests calling other unit tests 上的一篇文章中,总体感觉似乎是单元测试应该调用其他测试: 这个问题的答案似乎是你应该重构你的设置,所以 测试用例不相互依赖。

但是“setup-with-asserts”和“setup-with-asserts”并没有太大区别 单元测试调用其他单元测试。

因此我的问题是:在设置方法中有断言是一种好习惯吗?

编辑:

答案是:一般来说,这不是一个好习惯。如果设置结果需要测试,建议单独添加一个带有断言的测试方法(答案我勾选了);要记录意图,请考虑使用 Java 断言。

【问题讨论】:

阅读这篇关于编写好的单元测试的文章:blog.codeville.net/2009/08/24/… 【参考方案1】:

我使用了一个简单的测试(与其他测试方法类似,但定位为第一个测试方法),而不是设置中的断言来检查结果。

我已经看到了几个优点:

设置简短且重点突出,以提高可读性。 断言只运行一次,更高效

使用与讨论

例如,我将方法命名为 testSetup()。

要使用它,当我在那个类中有一些测试错误时,我知道如果 testSetup() 有错误,我不需要为其他错误而烦恼,我需要先修复这个。

如果有人对此感到困扰,并希望明确此依赖关系,则可以在 setup() 方法中调用 testSetup()。但我不认为这很重要。我的观点是,在 JUnit 中,您已经可以在其余的测试中拥有类似的东西:

    一些测试本地代码的测试, 以及一些调用更多全局代码的测试,这些测试间接调用了与上一个测试相同的代码。

当您读取两个都失败的测试结果时,您已经必须处理不在测试中而是在被调用代码中的这种依赖关系。您必须先修复简单测试,然后重新运行全局测试以查看它是否仍然失败。 这就是为什么我不会被我之前解释的隐式依赖所困扰的原因。

【讨论】:

今天早上我和一位同事讨论了这个问题,我们也想出了这个解决方案。很高兴听到您对此有积极的体验! @Kaka 感谢您的敏锐评论,以及您的反馈所提供的强化。 :-) @KLE:这是一个有趣且有效的策略。但是我想知道当您使用过滤器(即--gtest_filter)执行测试时,如何确保执行testSetup()【参考方案2】:

不建议在 Setup/TearDown 方法中使用断言。如果用户需要“理解”某些测试逻辑不在测试方法中,它会使测试的可读性降低。 有时您别无选择,只能将设置/拆卸方法用于其他用途,而不是预期用途。

这个问题有一个更大的问题:一个测试调用另一个测试,它是你测试中某些问题的味道。 每个测试都应该测试代码的一个特定方面,并且应该只有一个或两个断言,所以如果你的测试调用另一个测试,你可能在那个测试中测试了太多东西。 更多信息请阅读:Unit Testing: One Test, One Assertion - Why It Works

【讨论】:

指向一个测试/一个断言的有趣指针,我喜欢你将其改写为“一两个”。 网址已损坏。这是一个更新的。 Unit Testing: One Test, One Assertion - Why It Works【参考方案3】:

它们是不同的场景;我看不出有什么相似之处。

设置方法应该包含(理想情况下)所有在夹具中的测试通用的代码。因此,如果在测试代码的其余部分执行之前某些事情必须为真,那么在测试设置方法中放置断言本身并没有错。设置是测试的扩展;它是整个测试的一部分。如果断言失败,人们将发现哪个先决条件失败。

另一方面,如果设置复杂到您觉得需要断言它是正确的,则可能是一个警告信号。此外,如果所有测试都不需要设置的完整输出,则表明该夹具的内聚性较差,应根据场景进行拆分和/或重构。

部分原因是我倾向于远离使用设置方法。在可能的情况下,我使用私有工厂方法或类似方法进行设置。它使测试更具可读性并避免混淆。有时这是不切实际的(例如,使用紧密耦合的类和/或编写集成测试时),但对于我的大多数测试来说,它可以完成这项工作。

【讨论】:

【参考方案4】:

跟随你的心/眨眼决定。 Setup 方法中的断言可以记录意图;提高可读性。所以我个人会支持你。 它与调用其他测试的测试不同——这很糟糕。没有测试隔离。一项测试不应影响另一项测试的结果。

虽然它不是一个频率用例,但我有时会在 Setup 方法中使用 Asserts,这样我就可以知道测试设置是否没有按照我的预期进行;通常当我处理不是我自己编写的组件时。显示“安装失败!”的断言失败在错误选项卡中 - 快速帮助我专注于设置代码,而不必查看一堆失败的测试。

设置失败通常会导致该夹具中的所有测试失败 - 这是您的鼻子很快就会闻到的气味。 '所有测试失败通常意味着安装失败'所以并不总是需要断言。这就是说要务实,看看你的具体情况并“添加口味”。

【讨论】:

好点——谢谢。这意味着将 JUnit 断言用于两个不同的目的:(1)文档意图; (2) 检查结果是否符合预期。【参考方案5】:

在需要这样的事情的情况下,我使用 Java 断言,而不是 JUnit 断言。例如当您使用其他一些实用程序类来设置测试数据时。:

byte[] pkt = pktFactory.makePacket(TIME, 12, "23, F2");
assert pkt.length == 15;

失败意味着“系统甚至无法尝试运行此测试”。

【讨论】:

我喜欢这个主意。这提出了一个普遍的问题,混合 Java 断言和 JUnit Assert 方法是否是一种好习惯,但我喜欢你的推理。

以上是关于单元测试:在设置方法中有断言是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章

在数据仓库(关系)中有外键是一种好习惯吗?

将函数放在 useEffect 中是一种好习惯吗?

在连接模型中验证 ID 是一种好习惯吗?

编写返回 void 的方法是一种好习惯吗?

向 POCO 添加方法或创建单独的类来更新 POCO 的值是一种好习惯吗?

在 Java 中更改参数是一种好习惯吗