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

时间:2009-09-03 07:38:15

标签: unit-testing refactoring fixtures assertions

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

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

在最近关于stackoverflow的unit tests calling other unit tests帖子中,一般的感觉似乎是单元测试调用其他测试: 这个问题的答案似乎是你应该重构你的设置,所以 测试用例不依赖于彼此。

但是“设置与断言”和a没有太大区别 单元测试调用其他单元测试。

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

编辑:

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

5 个答案:

答案 0 :(得分:15)

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

我已经看到了几个优点:

  • 设置保持简短且专注,以提高可读性。
  • 断言只运行一次,更强

使用和讨论

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

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

如果有人对此感到困扰,并且想要明确地使用此依赖项,则可以在setup()方法中调用testSetup()。但我认为这不重要。我的观点是,在JUnit中,你可以在其余的测试中找到类似的东西:

  1. 测试本地代码的一些测试,
  2. 和一些调用更多全局代码的测试,它间接调用与前一个测试相同的代码。
  3. 当你读取两个都失败的测试结果时,你必须要处理这个不在测试中但在被调用的代码中的依赖。您必须先修复简单测试,然后重新运行全局测试以查看它是否仍然失败。 这就是为什么我不会被我之前解释过的隐含依赖所困扰的原因。

答案 1 :(得分:9)

他们是不同的场景;我没有看到相似之处。

安装方法应该包含在灯具中(理想情况下)所有测试所共有的代码。因此,如果在执行其余测试代码之前某些事情必须为真,则将断言置于测试设置方法中并没有任何内在错误。设置是测试的扩展;它是整个测试的一部分。如果断言跳闸,人们将发现哪个先决条件失败。

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

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

答案 2 :(得分:9)

不建议在Setup / TearDown方法中使用断言。如果用户需要“理解”某些测试逻辑不在测试方法中,则会使测试的可读性降低。 有些时候你没有选择,只能将setup / teardown方法用于其他目的之外的东西。

这个问题存在一个更大的问题:一个调用另一个测试的测试,它是测试中某些问题的气味。 每个测试都应测试代码的特定方面,并且其中只应包含一个或两个断言,因此如果您的测试调用另一个测试,则可能在该测试中测试了太多内容。 有关更多信息,请阅读:Unit Testing: One Test, One Assertion - Why It Works

答案 3 :(得分:3)

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

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

安装失败通常会导致该灯具中的所有测试失败 - 这是您的鼻子很快就会被吸收的气味。 '所有测试失败通常意味着安装程序破坏'因此并不总是需要断言。这说实话,看看你的具体情况和'添加品味'。

答案 4 :(得分:3)

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

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

失败意味着'系统未处于尝试运行此测试的状态'。