Unit testing 向遗留代码添加单元测试

Unit testing 向遗留代码添加单元测试,unit-testing,legacy-code,Unit Testing,Legacy Code,您是否曾经在遗留代码中添加过单元测试?代码有多复杂,存根和模拟一切有多困难?最终结果值得吗?如果您计划重构遗留代码,那么必须创建这些单元测试。不要担心模拟或存根-担心测试系统的输入和输出,这样您的更改或重构工作就不会破坏当前的功能 我不会骗你,将单元测试改造成遗留代码是困难的,但它是值得的。是的,而且通常是痛苦的。我常常不得不写集成测试 这本书在这方面有一些很好的建议。它还推荐了这本书;我还没有读过后者,但它在我的书堆上 编辑:但是是的,即使是最小的代码覆盖率也是值得的。它给了我信心和重构代码的

您是否曾经在遗留代码中添加过单元测试?代码有多复杂,存根和模拟一切有多困难?最终结果值得吗?

如果您计划重构遗留代码,那么必须创建这些单元测试。不要担心模拟或存根-担心测试系统的输入和输出,这样您的更改或重构工作就不会破坏当前的功能


我不会骗你,将单元测试改造成遗留代码是困难的,但它是值得的。

是的,而且通常是痛苦的。我常常不得不写集成测试

这本书在这方面有一些很好的建议。它还推荐了这本书;我还没有读过后者,但它在我的书堆上

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


编辑:我确实读过《有效地使用遗留代码》,这本书非常棒。

Michael Feathers的书《有效地使用遗留代码》是一本涵盖这一主题的整本书。Michael指出,为遗留代码引入测试通常太困难了,因为它的结构不是可测试的。我从这本书中得到的最多的是两种模式,分别命名为“Sprout函数”和“Sprout类”。sprout函数封装了需要在代码中进行的更改。然后只对这些函数进行单元测试。sprout类的想法是相同的,只是新功能包含在一个类中。

我发现,最好的方法是以增量方式添加单元测试,而不是直接跳进去说我们现在将对应用程序进行单元测试

因此,如果您打算修改代码,进行bug修复或重构,那么首先编写单元测试。对于bug,单元测试将有助于证明问题所在,因为您可以复制它

如果进行重构,您将希望编写单元测试,但您可能会发现该测试无法编写,因此您可能需要找到一个调用将被重构的函数的高层,并对该部分进行单元测试。然后,在重构攻击性函数时,编写测试,以确保其正常运行

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

这个问题可能有助于提出更多建议。

单元测试的另一种替代方法是。我在这些测试中得到了有趣的结果。它们比单元测试更容易设置,因为您从一个点进行测试,而不是可以进行测试(称为seam)。缺点是,当测试失败时,您对问题位置的提示较少,因为测试区域可能比单元测试大得多。日志记录在这里很有用


单元测试框架(如xUnit系列的框架)可用于编写特性测试

在这样的测试中,在事实之后编写,断言验证代码的当前行为。与单元测试不同,它们不能证明代码是正确的,它们只是固定(表征)代码的当前行为

该过程与TDD过程类似:

  • 为部分代码编写测试
  • 执行它-失败
  • 根据观察到的代码行为修复测试
  • 执行它-通过
  • 重复
如果修改代码的外部行为,测试将失败。代码的外部行为?听起来熟悉吗?是的,我们到了。现在您可以重构代码了


显然,风险取决于表征测试的覆盖范围

看看免费的开源单元测试实用程序库。如果您是.NET开发人员,那么创建者Llewellyn Falco已经展示了他如何使用ApprovalTests来改进新代码和旧代码的单元测试。

我不久前在XPDays上谈到了旧代码中反向测试金字塔的想法

本演示应该回答这样一个问题:为什么在处理遗留代码时,有时从集成/功能测试甚至高级验收测试开始是如此重要。然后慢慢地,一步一步地引入单元测试。这里没有代码示例-抱歉,但您可以在Michaels Feathers的《有效地使用遗留代码》一书中找到它们


此外,您还可以查看遗留代码撤退,并在您所在的地区寻找该会议

再看看遗留代码单元测试领域的新方法-,它受项目启发,并分享其关键概念

正如在以下章节中提到的认可测试方法:

通常,您有一个巨大的遗留代码项目,在该项目中您没有测试 全部,但您必须更改代码以实现新功能,或者 重构。遗留代码的有趣之处在于——它可以工作!信息技术 不管它是怎么写的,它都能工作多年。这是一个非常好的例子 该代码的优点。通过批准,您只需进行一次测试即可获得 所有可能的输出(HTML、XML、JSON、SQL或任何可能的输出) 是)和批准,因为你知道-它的工作!完成后 这样的测试和批准的结果,你真的是更安全的一个 重构,因为现在你“锁定”了所有现有的行为

Asis工具正是通过自动创建和运行特性测试来维护遗留代码的

有关更多信息,请参阅

  • 详细信息请参见项目的github回购协议

+1代表“有效处理遗留代码”:充满了伟大的建议;事实上,即使是在绿地环境中,它也值得一读,就像构建可测试性代码的伟大资源一样。通过适当的模拟,前者已经足够好了,通常+1用于增量添加测试。希望它能给我带来一些好处