引言
虽然应用程序代码库和测试代码库方法之间的辩论仍在继续,但混合解决方案提供了一个可行的折中方案。
项目的测试代码应该存在哪里?这是一场长达几十年的辩论
自从软件工程社区开始将软件测试作为软件开发生命周期(SDLC)的一部分以来,我们就一直在争论测试自动化代码的合适的保存地点。测试自动化代码是否应该与它验证的应用程序代码(“应用程序代码库”)保存在同一代码库中?或者还是最好将其放在一个单独的代码库中,远离主代码库(“测试代码库”)?这场辩论几乎和制表符与空格的争论一样激烈。
本文探讨了双方的观点,同时指出了每种方法的利弊。基于作者的经验和与工程团队成员的讨论,本文提出了一个混合解决方案。本文强调了“质量文化”的重要性,以及质量工程师作为质量倡导者的作用。它还讨论了预提交钩子的实现和在pytest中使用标签来创建快速反馈,以及高效的持续集成和交付/开发(CI/CD)流水线(pipeline)。最终认为 需要进行更多的研究,来指导QA社区的最佳实践。
辩论的内容是什么?
谁是现代的Hatfields 家族和McCoys家族(有世仇的两个家族)?让我们更仔细地看看这些群体。
为了清楚起见,我不会讨论自动化代码是否应该采用与主代码库相同的编程语言的相关争议。我们将把那个话题留到下次。
应用程序代码库拥护者表示:在应用程序代码库中维护测试代码更容易
应用程序代码库拥护者强烈认为,任何与应用程序代码库有关系的东西都应该位于该应用程序代码库中。这会包含单元测试以及任何测试自动化代码。这种结论通常基于团队使用的测试自动化框架,以及认为这样的话维护测试自动化代码就更容易的想法。测试代码代码库拥护者表示:考虑测试代码的复杂性
测试代码代码库拥护者倾向于考虑测试自动化项目的复杂性。并且他们认为只有应用程序代码才应该保存在应用程序代码库里面。
试验和错误是我们最好的信息来源
在我写这篇文章时,我试着找出是否有人进行过正式的研究来证明这些决定是如何做出的,以及在实践中测试代码通常保存在哪里。不幸的是,我没有找到这样的研究。因此,我不得不依靠道听途说和我自己在这件事上的经验。让我们来更深入地了解这两种方式的利与弊。
两种方式的利与弊
使用应用程序代码库的优点
- 在应用程序代码库中保留自动化代码可以确保测试始终与最新的应用程序代码更改同步。
- 每个人都可以在单个代码库中跟踪应用程序和测试代码的变化。
- CI/CD流水线可以在构建应用程序代码的同时更轻松地访问和运行测试。
- 改善了开发人员和测试人员之间的协作,促进更好的沟通和协同质量保障意识。
- 应用程序和测试代码共享一致的环境。
- 应用程序代码的更改可以立即测试,而无需在代码库之间切换。
- 减少维护开销,因为只需要管理一个代码库。
- 开发人员和测试人员可以互相审查代码。
- 在同一个地方管理共同的依赖项。
- 更轻松地调试失败的测试。
使用应用程序代码库的缺点
- 组合应用程序和测试代码会使存储库更加杂乱无章,更难浏览。
- 同一存储库中有更多的代码,合并冲突的可能性会增加。
- 作为同一流水线的一部分,运行测试可能会减慢构建过程,特别是如果测试套件很多的时候。
- 测试代码可能会暴露敏感信息或内部API,这些信息或内部API不应该从主应用程序代码库访问。
- 在应用程序代码库中保留测试代码可能会限制跨多个项目或应用程序重复使用测试的能力。
- 如果与应用程序代码混合,开发人员可能会不那么专注于编写和维护高质量的测试代码,这可能会导致忽视测试实践。
- 随着项目的开发,为应用程序和测试代码维护单个存储库可能会变得笨重,更难管理。
- 混合应用程序和测试代码可能会模糊开发和测试责任之间的界限。
- 在同一存储库中管理应用程序和测试代码的依赖项可能会导致冲突,并且增加复杂性。
- 不同的团队可能需要不同的访问权限,在同一存储库中同时使用应用程序和测试代码可能会使访问控制管理复杂化。
使用单独的测试代码repo的优点
- 保持应用程序库专注于应用程序代码,可以使其更容易浏览和管理。
- 测试代码可以独立于应用程序代码进行版本化。
- 单独的测试代码代码库可以促进在多个项目中重复使用测试代码。
- 可以为测试代码代码库设置不同的访问权限,只允许特定团队成员修改测试脚本。
- 通过将测试代码分开可以减少应用程序代码库的大小。
- 区分应用程序和测试代码可以更轻松地管理和理解项目的每个部分。
- 特定于测试的依赖项可以独立管理,避免与应用程序依赖项的潜在冲突。
- 团队可以在不影响主应用程序代码的情况下处理测试代码,允许并行开发和测试工作。
- 拥有一个单独的测试代码代码库可以更容易地扩展测试工作。
使用单独的测试代码代码库的缺点
- 保持测试代码与应用程序代码更改同步可能具有挑战性。
- 维护测试代码版本与应用程序代码版本的一致性可能有挑战性。
- 对应用程序代码的更改可能不会立即反映在测试中,从而可能会延迟问题的发现。
- 开发人员和测试人员更难合作。
- 将测试从单独的代码库集成到CI/CD流水线中可能更加复杂,并且需要额外的配置
- 管理两个独立的存储库需要更多的精力和时间。
- 审查两个存储库的更改可能既耗时又复杂。
- 共享资源或实用工具程序可能会在存储库之间重复。
- 开发人员对测试代码的可见性可能较低,这可能会导致开发和测试工作之间的脱节。
- 新团队成员可能需要配置和理解两个独立的存储库,从而增加学习曲线。
分享:代码库问题的混合解决方案
哇,双方观点都是各有所长。难怪这个争论从未得到彻底解决。我能做的事就是提供一个可能对许多组织有效的折衷方案。为什么需要选择一种方法,而实际上混合方法效果最好?
根据我自己的经验,以及与工程团队成员在开发和测试方面的多年的对话,我提出了自己的建议。测试计划就像baklava(巴克拉瓦-中东的著名甜点)一样,因为它有很多层,精心构建,当做对时,它会是一个甜蜜的成功。 😆
哪类代码应该放在应用程序代码库中呢?
单元测试应该是应用程序代码库的成员
根据我的经验和与QA(质量保障)社区其他成员的交谈,单元测试的最佳保存地点是应用程序代码库。我认为我们没有看到很多争论说单元测试应该独立出去存在于它自己的测试代码库。合同测试在应用程序代码库中效果最佳
在应用程序代码库中包含的第二种测试是合同测试。合同测试是一种测试方法,它通过验证两个系统之间的“合同”是否正确执行,来确保这两个系统(如服务或微服务)能够按预期的那样进行相互通信和交互。
通常情况下,我会要求集成测试保存在应用程序库(repo)之外,原因我稍后会列出。然而,合同测试是一种特殊的集成测试。这是确保服务之间能正确通信的最佳方法,还没有全面端到端测试的开销。在应用程序代码库中进行测试
我会把单元和合同测试包含在预提交钩子(pre-commit hook)里面,同时在其中也包含lint(代码辅助分析工具)、静态代码和安全分析工具。这种做法为开发人员创建了一个快速的反馈,并确保创建的拉取(pull)请求服从已安装的进程。
哪类代码应该存在测试代码库中呢?
简单来说就是所有其他类型的测试!
我建议所有其他类型的测试都应位于应用程序库之外,也就是保在其自己的测试代码库中。退后一步思考:为什么我们要使用不同层面的测试?我们想要得到什么?在测试代码代码库中添加基础设施并限制模拟测试
当您计划进行集成、功能、可访问性、端到端和其他类型的测试时,您希望将基础设施作为正在测试的组件之一,并希望尽可能限制模拟测试。在测试代码库中使用pytest标签对测试进行分组
我也相信DRY(不要重复自己)原则,并认为将测试自动化代码保留在同一代码库中是有意义的,这样可以减少代码和逻辑的重复,从而提高可维护性并减少错误。
您应该在pytest中使用类似“标签”的概念,将相关测试分组到多个测试套件中。然后,这些测试套件可以在CI/CD流水线中使用。
在CI/CD流水线中,在预提交钩子成功并开始准备创建拉取请求后,您需要使用我们之前谈论的套件标签开始添加测试层。
在这种场景下,您只需要创建一个测试代码库的访问权限。然后您就可以运行相关的测试。给合适的人员发送测试失败通知
一个好的QA倡导者关注的最后细节是确保团队快速收到故障通知,从而使数据可见。但不幸的是,根据我的经验和与他人交谈得知,一旦CI/CD流水线运行起来,就没有人会监控它直到完成。我们需要确保我们作出快速反馈,并在测试失败时通知合适的人员。我们还必须收集历史数据来监测趋势以确定改进情况。
混合代码库方法快速一瞥
我们对测试策略的探索凸显了全面方法对确保软件质量和可靠性的重要性。从预提交钩子到CI/CD流水线,从单元测试到安全测试,每一个步骤在整个测试流程中都发挥着至关重要的作用。下面的表格总结了这一流程关键部分,进一步强调了QA社区需要进一步研究和标准化。
表1:适合应用程序存储库和测试代码存储库的测试类型和工具
预提交钩子(应用程序代码库) | CI/CD管道(测试代码代码库) |
---|---|
单元测试 | 冒烟测试 |
合同测试 | 基本功能测试 |
lint(代码辅助分析工具) | API 测试 |
静态代码分享 | UI 测试 |
静态安全分析 | 安全测试 |
QA社区应该考虑进行更多的研究来指导最佳实践,但与此同时,我们的经验是我们唯一可以依靠的。
总结一下
总之,虽然应用程序代码库和测试代码代码库方法之间的辩论仍在继续,但混合解决方案提供了一个可行的折衷方案。通过将单元测试和合同测试保留在应用程序代码库中,并将其他类型的测试保留在单独的代码库中,团队可以从这两种方法的优势中同时受益。这种策略提倡质量文化,并促进左移测试,最终形成更高效、更有效的软件开发流程。