Unit testing 单元测试:在设置方法中使用断言是一种好的实践吗?

Unit testing 单元测试:在设置方法中使用断言是一种好的实践吗?,unit-testing,refactoring,fixtures,assertions,Unit Testing,Refactoring,Fixtures,Assertions,在单元测试中,setup方法用于创建测试所需的对象 在这些设置方法中,我喜欢使用断言:我知道我希望在这些方法中看到什么值 对象,我喜欢通过断言来记录这些知识 在最近一篇关于stackoverflow的文章中,人们普遍认为单元测试不应该调用其他测试: 这个问题的答案似乎是你应该重构你的设置,所以 测试用例之间并不相互依赖 但是“带有断言的设置”和 单元测试调用其他单元测试 因此我的问题是:在设置方法中使用断言是否是一种好的做法 编辑: 答案是:这通常不是一个好的做法。如果需要测试设置结果,建议添加

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

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

在最近一篇关于stackoverflow的文章中,人们普遍认为单元测试不应该调用其他测试: 这个问题的答案似乎是你应该重构你的设置,所以 测试用例之间并不相互依赖

但是“带有断言的设置”和 单元测试调用其他单元测试

因此我的问题是:在设置方法中使用断言是否是一种好的做法

编辑:


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

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

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

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


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

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

这个问题中有一个更大的问题:一个调用另一个测试的测试,它是测试中某个问题的气味。 每个测试都应该测试代码的一个特定方面,并且应该只有一个或两个断言,因此如果您的测试调用另一个测试,那么您可能在该测试中测试了太多的内容。
有关更多信息,请阅读:

遵循你的心/眨眼决定。设置方法中的断言可以记录意图;提高可读性。所以我个人会支持你的。
它不同于调用其他测试的测试,这是不好的。没有测试隔离。一项测试不应影响另一项测试的结果

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


设置失败通常会导致该设备中的所有测试失败,这是一种你的鼻子很快就会闻到的气味所有测试失败通常意味着安装程序已中断,因此并不总是需要断言。也就是说,要务实,看看你的具体环境,然后“增加品味”。

我没有在设置中使用断言来检查结果,我使用了一个简单的测试(一种与其他测试方法相同的测试方法,但定位为第一种测试方法)

我看到了几个优点:

  • 设置保持简短和集中,以便于阅读
  • 断言只运行一次,效率更高

使用和讨论

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

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

如果有人对此感到困扰,并希望使此依赖项显式化,则可以在setup()方法中调用testSetup()。但我认为这无关紧要。我的观点是,在JUnit中,您可以在其他测试中使用类似的内容:

  • 一些测试本地代码的测试
  • 有些测试调用更多的全局代码,这间接调用了与前一个测试相同的代码
  • 当您在两个测试都失败的情况下读取测试结果时,您必须处理这个依赖关系,它不在测试中,而是在被调用的代码中。您必须首先修复简单测试,然后重新运行全局测试以查看它是否仍然失败。
    这就是为什么我没有被我之前解释过的隐式依赖所困扰的原因。

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

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

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

    阅读这篇关于编写好的单元测试的文章:今天早上我与一位同事讨论了这个问题,我们也提出了这个解决方案。很高兴听到你在这方面有积极的经验@卡卡感谢您的热情评论,以及您的反馈所提供的支持。:-)@这是一个有趣而有效的策略。但是我想知道你如何确保
    tes