向遗留代码添加unit testing

你有没有添加unit testing,事实上,遗留代码? 代码有多复杂,有多困难的存根和模拟一切? 最终结果是否值得?

我发现最好的方法是逐步添加unit testing,而不是跳进来,并说我们现在将unit testing应用程序。

因此,如果您要触摸代码,进行错误修复或重构,请先编写unit testing。 对于错误unit testing将帮助certificate问题出在哪里,因为您可以复制它。

如果重构,你会想编写unit testing,但你可能会发现testing是不可能写的,所以你可能需要find一个高层次的,调用将被重构的函数,并unit testing该部分。 然后,当你重构进攻性function时,写下你的testing,以确保它能够正常运行。

有没有简单的方法来做到这一点。

这个问题可能有助于更多的build议。 你如何将unit testing引入一个大的,传统的(C / C ++)代码库?

迈克尔羽毛书“与遗产代码有效地工作”是涵盖这个主题的整本书。 Michael指出,为遗留代码引入testing通常太困难了,因为它没有被构build为可testing的。 我从书中得到的最多的是一些名为“Sproutfunction”和“Sprout类”的模式。 萌芽function是封装您需要在代码中进行的更改的function。 然后你只能unit testing这些函数。 除了新function包含在类中,萌芽类是相同的想法。

是的,这通常是痛苦的。 我经常最终不得不编写集成testing。

“ unit testing的艺术”这本书有一些很好的build议。 它还build议“ 有效使用遗产代码 ”一书。 我还没有阅读后者,但它在我的堆栈上。

编辑:但是,即使最小的代码覆盖面是值得的。 这给了我重build代码的信心和安全网。

编辑:我没有阅读与遗产代码有效地工作,这是非常好的。

特性testing是unit testing的另一种替代方法,也是与传统代码一起有效地工作的。 我有这样的testing有趣的结果。 他们比unit testing更容易设置,因为从testing点开始testing(称为接缝)比unit testing更容易。 缺点是,当一个testing失败时,你对问题的位置的暗示就会less一些,因为被测区域比unit testing要大得多。 logging在这里有帮助。


unit testing框架,如xUnit系列的unit testing框架,可以用来编写特性testing。

在这样的testing中,事实之后,断言validation了代码的当前行为。 与unit testing不同,它们不能certificate代码是正确的,只是将代码的当前行为固定(表征)。

这个过程与TDD类似:

  • 写一部分代码的testing
  • 执行它 – 失败
  • 从观察到的代码行为中修复testing
  • 执行它 – 通过
  • 重复

如果修改代码的外部行为,testing将失败。 代码的外部行为? 听起来很熟悉 ? 是的,我们在这儿。 现在你可以重构代码。

显然风险取决于特征testing的覆盖范围。

如果您打算重构遗留代码,那么创build这些unit testing是必须的。 不要担心模拟或存根 – 担心testing系统的input和输出,以便您的更改或重构工作不会中断当前的function。

我不会骗你,对遗留代码进行unit testing是很困难的 – 但这是值得的。

看看免费的开源unit testing工具库ApprovalTests 。 如果您是.NET开发人员,创build者Llewellyn Falco已经制作了一系列video,展示他如何使用ApprovalTests来改进新代码和旧代码的unit testing。

还要关注遗留代码unit testing领域的新方法–Asis项目 ,它受到了ApprovalTests项目的启发,并分享了其关键概念。

正如本文中提到的ApprovalTests方法:

通常你有一个巨大的遗留代码项目,你根本没有testing,但你必须改变代码来实现一个新的function,或重构。 遗留代码有趣的是 – 它的工作原理! 不pipe它是怎么写的,它都可以工作多年。 这是该代码的一个非常大的优势。 通过审批,只需一次testing,您就可以获得所有可能的输出(HTML,XML,JSON,SQL或任何可能的输出)并获得批准,因为您知道 – 它可行! 完成这样一个testing并批准结果之后,由于现在您已经“locking”了所有现有的行为,所以对于重构而言确实更安全。

Asis工具正是通过自动创build和运行特性testing来完成对遗留代码的维护。

欲了解更多信息,请看

  • 详细的README在项目的github回购
  • 关于黑客新闻的讨论
  • 讨论reddit.com/r/php
  • 讨论reddit.com/r/programming

前段时间我一直在说XPDays中遗留代码的反转testing金字塔的概念http://xpdays.com.ua/archive/xp-days-ukraine-2012/materials/legacy-code/

这个演示文稿应该回答为什么有时候使用遗留代码开始集成/function甚至高层验收testing的问题。 然后慢慢地,逐步引入unit testing。 没有代码示例 – 对不起,但是你可以在Michaels Feathers的书“使用遗留代码有效地工作”中find一堆代码。

您也可以查看传统代码撤退http://www.jbrains.ca/legacy-code-retreat,并在您所在地区寻找会议。;