我们有12个遗留项目。一个是9年前编程的旧Visual Basic应用程序,另一个是C#(.NET)应用程序,2个Java项目和操作系统。
我们刚刚完成了清理并为每个项目创建一个存储库(其中一些只是位于不同计算机上的文件夹......
我们已经为 Jenkins 配置了许多有用的插件,买了两本书:持续集成和持续交付,还没有完全阅读。
我们为项目定义了部署管道。所有这些都在提交到存储库后自动编译,并且自动完成代码分析(圈复杂性等)。
但是,我们想知道是否有可用于项目的测试(易于添加)。我们知道单元测试,但是,为这些项目编写单元测试太耗时了(如果可能的话)。
我们是否可以添加其他类型的测试或我们可以添加到管道中的其他有用内容?
对于某些程序,我们正在自动生成安装程序。
此外,在管道的末尾,我们有一个手动步骤,将二进制文件(安装程序)移动到我们 apache 服务器上的公共文件夹中,公司中的人们可以轻松获得最后一个稳定的二进制文件(这里稳定是我们手动安装和测试的应用程序(我认为它被称为探索性测试),如果我们没有看到任何错误, 我们将其推广为稳定版本)。
我通常应用三个级别的测试:
- 单元测试 - 验证小型独立代码单元正确行为的低级测试。这些测试通常是低级的,直接调用其他代码/API,运行速度快(在构建期间),并且在进行大量重构时也会相对较快地中断。
- 集成测试 - 中级测试,用于验证多个代码单元的正确行为。例如,后端提供给外部系统或前端的 API。这些测试通常不是太低级,运行在代码级别之上(例如 http 请求),运行速度比单元测试慢一点(仍在构建时),但由于它们针对系统边界进行测试(例如 REST 端点),因此中断速度较慢。
- 端到端测试 - 测试整个系统的高级测试。对于Web应用程序,通常使用浏览器测试(例如使用Selenium),其中浏览器由测试控制,连接到系统的运行实例。这些测试是相当高级别的(它们模拟用户行为),运行缓慢,而不是在构建时(因为需要首先部署系统)。
在您的情况下,我会将这些类型的测试结合起来。首先使用集成测试和/或端到端测试创建自动回归测试套件。这些类型的测试可以毫不费力地击中系统的相对大部分。添加/更改功能时,首先编写一个或多个单元测试来验证系统的当前状态。然后添加/更改测试用例,以验证系统的所需/新状态,并相应地更改系统。
顺便说一下:请重新考虑"为这些项目编写单元测试太耗时"的说法。是的,这可能很耗时,但根本不编写测试也很耗时,因为您可能会在不知情的情况下一直破坏功能,并发现自己需要解决很多问题。
与其像现在这样为所有内容编写单元测试,我相信您最好为您添加的新代码编写单元测试。您可以假设在当前状态下,一切都按预期工作;然后,当您发现并修复错误,或添加新功能,或对代码库进行任何更改时 - 为该新代码编写单元测试。
对于其他类型的测试,您可能需要考虑集成测试。这个对另一个 SO 问题的回答解释了集成测试的用途以及它们与单元测试相比的价值。
,也许一年后有点晚了......但无论如何,对于路过这里的人来说。
持续交付是敏捷技术的高级联盟。对于大量的遗留代码块,您可能不会在相当长的一段时间内变得"连续"。学习这些想法,但如果你还不能达到它们,不要感到沮丧。
设置存储库和管道仍然是一个好主意。存储库允许您快速回滚有缺陷的更改。管道为您提供了运行大量测试所需的自动化功能,以掌握代码。
您不需要任何其他工具或更多插件。您的编程语言很可能已经拥有您需要的一切。您需要的是专业知识、信念和耐心。以下是对我们的团队有用的方法:
了解 Michael Feather's Effective Working Legacy Code。它为您提供了开始修改旧代码所需的技术,而不必担心破坏它。您认为无法为旧代码编写单元测试吗?你错了。羽毛告诉你怎么做。这是专有技术部分。
此外,了解什么是表征测试及其工作原理。你失去了员工,从而失去了专业知识。那个代码似乎没有人知道或记得它的作用?表征测试可帮助您探测它并使您能够重构它。
不要为了"让你的代码再次伟大"而开始一个庞大的项目。编写代码需要一段时间,修复它需要一段时间。逐段获取待测试代码。每当您开发新功能时,请为该功能及其立即连接到的旧代码编写测试。修复 bug 时,首先围绕要修复的代码编写单元测试。这将增加您的代码覆盖率,同时仍然可以让您完成实际工作。这是耐心的部分。
每周,获取一个完全被测试的资源(类、方法、函数),即语句和分支覆盖率为 100%。拥有 100% 覆盖率的 1 个资源比覆盖率为 10% 的 10 个资源更好。
原因如下:现在可以重构该资源。阅读 Robert C. Martin 的 Clean Code,了解如何改进代码。然后召集一些团队成员进行重构会话:
做一个小小的改进(重命名一个变量,删除一个注释,提取一个子方法),然后证明所有测试仍然是绿色的,然后将键盘传递给房间里的下一个人。在整个会话中一遍又一遍地重复此操作。不要忘记在这些会议中添加糖果,薯条,可乐或啤酒 - 使其成为一个有趣的活动。
使用会话来了解代码、它的作用以及原因;这将使房间里的所有人都能够支持他们本来不会接触的代码。
它还让人们知道他们编写所有这些单元测试的目的:重构代码。如果没有他们,他们可能会认为这些单元测试只是一些更无用的负担。毕竟,有时需要首先处理的是遗留开发人员,而不是遗留代码。这是信念部分。