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