事后,您是否曾经将单元测试添加到旧代码中?代码有多复杂,存根和模拟一切有多难?最终结果值得吗?
事后,您是否曾经将单元测试添加到旧代码中?代码有多复杂,存根和模拟一切有多难?最终结果值得吗?
Answers:
我发现,最好的方法是逐步添加单元测试,而不仅仅是加入并说我们现在将对应用程序进行单元测试。
因此,如果您要触摸代码以进行错误修复或重构,请首先编写单元测试。对于错误,单元测试将帮助您证明问题出在哪里,因为您可以将其复制。
如果进行重构,您将要编写单元测试,但是您可能会发现该测试无法编写,因此您可能需要找到一个高层,调用将要重构的函数,并对该部分进行单元测试。然后,在重构进攻功能时,编写测试,以确保其正常运行。
没有简单的方法可以做到这一点。
这个问题可能会提供更多建议。 如何将单元测试引入大型的(C / C ++)代码库中?
还要看看遗留代码单元测试领域中的新方法-Asis项目,它受ApprovalTests项目的启发,并共享其关键概念。
随着对ApprovalTests提到在接近这篇文章:
通常,您有一个庞大的旧代码项目,根本没有测试,但是您必须更改代码以实现新功能或重构。关于遗留代码的有趣之处在于-它可以工作!无论如何编写,它都能工作多年。这是该代码的一大优势。有了批准,只需进行一项测试,您就可以获取所有可能的输出(HTML,XML,JSON,SQL或可能的任何输出)并批准,因为您知道-它可以工作!在完成了这样的测试并批准了结果之后,通过重构,您实际上会更加安全,因为现在您可以“锁定”所有现有行为。
Asis工具正是关于通过自动创建和运行表征测试来保留旧代码的方法。
有关更多信息,请参见
表征测试也是有效使用遗留代码中引入的单元测试的一种替代方法。通过这些测试,我得到了有趣的结果。从点进行测试比进行单元测试(称为接缝)要容易,因此它们比单元测试更容易设置。缺点是,当测试失败时,您对问题所在的提示会更少,因为被测试的区域可能比单元测试大得多。日志记录在这里有帮助。
诸如xUnit系列之类的单元测试框架可用于编写特性测试。
在事实之后编写的此类测试中,断言可验证代码的当前行为。与单元测试不同,它们不能证明代码正确无误,它们只是确定(表征)代码的当前行为。
该过程类似于TDD的过程:
如果您修改代码的外部行为,则测试将失败。代码的外部行为?听起来很熟悉 ?是的,我们来了。现在您可以重构代码。
显然,风险取决于表征测试的覆盖范围。
查看免费的开源单元测试实用程序库ApprovalTests。如果您是.NET开发人员,则创建者Llewellyn Falco制作了一系列视频,展示了他如何使用ApprovalTests来改进新代码和旧代码的单元测试。
如果您打算重构遗留代码,那么必须创建那些单元测试。不必担心模拟或存根-担心测试系统的输入和输出,以便您所做的更改或重构工作不会破坏当前的功能。
我不会骗你,将单元测试改造成遗留代码很困难-但这是值得的。
我前段时间一直在谈论XPDays的遗留代码中的反向测试金字塔的想法http://xpdays.com.ua/archive/xp-days-ukraine-2012/materials/legacy-code/
该演示文稿应回答以下问题:为什么在使用遗留代码时有时从集成/功能甚至高级验收测试开始如此重要。然后慢慢地,逐步引入单元测试。没有代码示例-抱歉,但是您可以在Michaels Feathers的著作“有效地使用旧版代码”中找到许多示例。
您也可以查看旧版代码撤退http://www.jbrains.ca/legacy-code-retreat并在您所在的地区寻找该会议。