13

我继承了一个没有单元测试的遗留 Web 应用程序。我想添加一些,但不知道从哪里开始。我应该将它们添加到旧代码中吗?或者只是新的代码?如果该代码与遗留代码交互怎么办?你有什么建议?

4

7 回答 7

9

首先,我建议对未来的所有更改进行单元测试,我想大多数人都会同意这是回归的好主意。

但是,对于现有代码,这是您需要查看您愿意或允许将多少风险引入产品的情况之一。问题在于,当您开始对现有代码库进行单元测试时,您将很快意识到重构和设计改进的许多机会。

听我说,如果你是一个优秀设计的坚持者,但你没有被授权做出激烈的重构决定,那么当你尝试为遗留部分编写测试时,你只会心碎- 是的,如果它没有现有的测试套件,它需要重构。如果不允许您对生产应用程序进行重大更改,那么您最终将实现我们喜欢称之为“垃圾适配器模式”的东西。祝你好运!

于 2008-12-05T02:06:47.113 回答
3

我建议获取一份有效地使用旧代码的副本。

我们在一个学习小组中浏览了这本书。这很痛苦,但很有用。

主题包括:

  • 了解软件变更的机制:添加功能、修复错误、改进设计、优化性能
  • 将遗留代码放入测试工具
  • 编写测试以防止引入新问题
  • 可用于任何语言或平台的技术,包括 Java、C++、C 和 C# 中的示例
  • 准确识别需要更改代码的位置
  • 处理非面向对象的遗留系统
  • 处理似乎没有任何结构的应用程序

您可以在http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf看到对此的简短介绍

于 2008-12-05T07:45:48.973 回答
2

旧版应用程序是分层的吗?

如果是这样,首先将单元测试添加到后端/业务层

如果没有,则将单元测试添加到新代码中,并在发现错误时(用于回归测试)

如果您有时间/雄心对整个事物进行单元测试(最终),请开始列出功能(首先是关键功能)并为这些功能添加单元测试,一次几个

于 2008-12-05T01:56:34.170 回答
2

如果它是您继承的代码,大概您必须开始阅读它并了解它做什么和不做什么。我建议您编写反映您对代码库不断增长的理解的单元测试。最终,您将建立关于遗留应用程序的知识体系,即“这些函数是通过这些测试的函数”,而不是“这些函数是具有这些实现的函数”。然后,您将有更多的自由和信心在不破坏事物的情况下进行更改。

于 2008-12-05T02:01:26.577 回答
2

我不会仅仅为了进行测试而编写任何测试。我只会在发现错误或添加新功能时编写测试。然后编写测试来装箱您需要更改/实现的代码,以定义它当前的功能。在出现错误的情况下,编写测试以证明错误已得到修复。在新代码的情况下,它应该做什么。现在去实现修复/新功能。如果你发现你很想触碰你的测试“盒子”之外的代码——写一些更多的测试来盒子那个区域(或者重新考虑你想要做的改变)。根据需要逐步引入新的测试,以最大限度地提高您在测试中的投资。编写测试来证明工作代码有效似乎毫无意义,直到它被证明被破坏。

于 2008-12-05T02:20:55.493 回答
1

如果 Web 应用程序没有经过单元测试,那么它也可能不容易进行单元测试。将其置于单元测试下可能会有风险,因为您没有 [单元] 测试,是的,鸡和蛋。此外,这需要时间并且不会为应用程序带来太多价值。

我的目标是使用SeleniumWatir、 HtmlUnit 或 HttpUnit 、 YMMV 为应用程序的遗留部分编写端到端自动测试。这些测试(特征测试)将确定您当前的应用程序行为,就像单元测试一样,但是从外部,允许您通过检测不希望的副作用的能力进行更改。

为新代码编写单元测试,以及在更改遗留代码时,无论是为了解决问题还是添加新功能。

于 2008-12-05T07:01:14.943 回答
1

在应用程序的已知“痛点”编写测试。经常中断或通常具有较高风险的代码是一个很好的起点,因为它有助于在该领域建立第一道防线,并使团队接触到该应用程序中单元测试的范围。

每次针对应用程序打开缺陷时,继续尝试编写单元测试以公开此行为。它会在修复时通知您,并希望防止将来再次引入它。

此外,寻找需要重构的代码。任何重构工作都应该以创建单元测试为开头。这有助于确保它在您进行更改之前和之后都能正常工作。重构一开始可能会很困难,因为存在“涟漪效应”的风险,其中一个破损可能会以意想不到的方式对整个应用程序造成严重破坏。

于 2008-12-07T15:39:58.247 回答