单元测试编写
迟早我们都会体验到测试绿灯的舒适感觉,可以确保在关键组件发生更改后,或者在重构后立即影响了多个内部相互作用的情况下,不会出现回归。 作为持续集成构建系统的一部分,对项目进行良好的测试覆盖可能是其主要优势:测试可能不会确实立即发现错误,但是在大多数情况下,它们应该Swift警告功能已损坏和任何重要的回归。 因此,我们想要并且我们需要依赖于单元测试,我们想要并且我们需要拥有适当而有效的单元测试。
因此,让我们尝试列出一个良好的单元测试的一些重要方面,这些方面肯定会提高假定的质量,然后证明您的构建质量(不,虽然我们没有在谈论任何元质量)。
隔离的
单元测试应独立于测试套件中的任何其他测试,而且给定单元测试的每种测试方法应独立于任何其他方法(它们可以单独运行)。 因此,应确保在测试级别隔离,也应在状态级别和订购级别确保隔离。 因此,测试应该在沙盒(如果需要的话,专用数据库,工作空间,数据输入集等)中运行。
如果真的需要一个测试,按照一定的顺序(罕见的情况下,可能进一步调查)来执行,你可以想想@FixMethodOrder提供注解的JUnit 4.11或更先进的方法,到@RunWith定制亚军 。
如果测试无法还原某些数据,请确保它不会影响任何其他测试(如果数据仅与被测功能相关,则不应该,但是如果受影响的数据在系统之间共享,则可能会发生) 。
可靠
我们应该始终依靠测试,我们应该信任它们的非回归和输入覆盖率(预期的输入/输出,空输入,边界情况,超出范围的输入以及其他类型的无效条件)。 我个人拒绝与单元测试的长度有关的“ 越短越好 ”的想法:确实,单元测试的方法应该短一些,但是单元测试的类可能很长,并且不一定意味着它是一个不好的编码测试,因为可能需要使用不同类型的输入,方案和前提条件来测试所测试的相关功能。 在这种情况下, 时间越长越好 ,也就是说,我们将确保测试覆盖尽可能多的特定组件,从而达到良好的可靠性水平。
请记住,尽管也将SRP( 单一职责原理 )也应用于测试代码,因此请不要在同一测试类中混合使用不同的功能(测试应该是唯一的且重点突出),而应尝试缩小每种方法的使用场景,因为只要涉及相同的功能。
如果您无法测试某些内容,请考虑进行重构,考虑进行模拟,再考虑进行注入。 尽管要在一定限制内使用模拟对象,但我们要依赖现有的经过测试的组件,而不是临时对象,不要通过模拟所有东西来使测试满意,请对其进行挑战。 尝试通过服务实现的构造函数注入依赖关系(例如,检查Google Guice方法)。 避免滥用PowerMock用法(模拟静态类,模拟最终类),而应重新考虑应用的设计! 实际上,当您在两个不同的设计之间进行选择时,请考虑如何测试相关组件:它可能会发现所建议解决方案之一的薄弱点,或者至少可以帮助您更好地理解依赖关系和耦合。
可读的
好的测试应该易于理解,维护,更改。 它实际上应该是自动记录其名称(类名,方法名),它的工作流程和主张,运用经典的AAA模式: 安排 (你的输入), 法 (使用功能测试), 断言 (结果)。 这就是为什么您应该始终对环境,数据,字段的通用设置使用设置和拆卸方法,对通用设置进行分组,并留下更具可读性的测试方法代码。
可读性还有助于减少代码中的冗余(DRY, 请勿重复使用 ,也适用于测试代码),将所需的测试支持代码分组为超类或帮助器类(首选方法)。 但是,请始终按功能,范围,领域对它们进行分组,不要以无休止的静态方法实用类结束,也不必测试您的测试支持代码,不要添加不需要的自定义测试框架(应用YAGNI也处于此级别, 您将不需要它 )。
可重复的
如果您的测试被正确隔离,那么它应该已经相当可重复了。 请记住,始终将系统(或测试所用的沙箱)恢复到其初始状态,也就是说,在启动测试之前(检查表计数,即使在测试失败的情况下删除任何已创建的条目)也要保持沙箱的状态不变,断言是否存在与环境相关的元素等等)。 不要依赖硬编码的值,例如标识符或记录键,这也将测试限制为某种行为(数据的预定义顺序,强加的匹配,提供的特殊情况),而应考虑生成随机或伪随机在这些情况下的值。 此外,使用日期时,请勿造成将来的失败!
快速
测试应该快速运行(以毫秒为单位,最差的秒数),这意味着它永远不会在I / O操作,连接超时,长时间运行的处理中被阻塞,或者至少永远不会在调用的功能之上增加太多开销。 请记住,单个测试的速度可能也相当慢,但是它将被添加到已经运行数百个测试的现有测试套件中,您不能等到构建结束才花几个小时。 因此,性能改进也一定程度上适用于测试代码:通常,您的测试代码与业务代码之间应该没有太大不同,因此,您应该应用相同的准则和编码标准,并且永远不要将其视为“第二”。 -班级代码。
自动化的
如果它已经是可重复的并且是隔离的(并且很快),那么在大多数情况下就可以轻松实现自动化。 那你做对了。 自动化不是测试的直接属性,确实是我们可能会使用它,也就是我们通常使用它的方式,并且只有在已经准备好特定测试的情况下,我们才能自动化它,并提供上述特性。
而已。 遵循这些简单的准则应有助于我们进行更有效的单元测试。 编写新的单元测试后,我们应始终仔细检查它们的可读性,想知道我们将如何依赖它们,它们是准确且孤立的。 无论我们是否采用测试驱动开发方法,我们的测试都应提供这些特征,并且我们的项目肯定会获得巨大的附加值。
翻译自: https://www.javacodegeeks.com/2014/02/write-effective-unit-tests.html
单元测试编写