几乎每个决定“认真对待测试”的团队都是从错误的地方开始的:选择工具。讨论了框架、插件、运行器,直到后来有人才意识到,毕竟没有人定义要测试什么以及如何测试。
该工具是最后的决定,而不是第一个决定。在此之前,结构选择将决定您的套房是资产还是自重。那些以正确的顺序定义这些选择的人创建了一个持续多年的基础。那些即兴创作的人组装了一套将在六个月内重写的套件。
这段文字是一个脚本。它不是松散的“良好实践”列表,而是当我需要从头开始构建产品的测试架构时遵循的步骤顺序。
步骤 1:在定义测试内容之前定义风险是什么
测试一切是不可能的,也是不必要的。第一个决定是了解产品的真正风险所在。
在支付系统中,风险在于价值的计算和交易的幂等性。在公共服务门户中,它在于对个人数据的访问资格和控制。在电子商务中,它位于购物车和结帐处。首先把这个映射出来。
该风险图定义了哪些地方值得进行深入测试,哪些地方只需进行简单检查就足够了。如果没有它,团队就会浪费精力测试琐碎的事情,而忽略关键的部分,这是最糟糕的情况。
步骤 2:建立级别及其边界
第二步是确定测试级别以及每个级别涵盖的内容。经典的金字塔可以作为指导:许多单元测试,一些集成,很少端到端。
比格式更重要的是每个级别的边界。单元测试在没有基础设施的情况下单独验证规则。集成测试验证组件或服务是否正确通信。端到端测试测试整个用户流程。
定义这些边界显然可以避免代价最高的错误:重叠测试。当在三个级别检查相同的行为时,任何更改都会破坏三个测试,并且套件会变得脆弱而无法获得信心。
步骤 3:确保与第一次测试隔离
隔热是最决定套房未来健康的属性,也是一开始最容易被忽视的属性。
每个测试都需要设置自己的场景并在最后清理它。任何测试都不能依赖于其他测试留在存储体、内存或文件系统中的内容。一旦测试假设“用户 X 已经存在”,您就已经埋下了一颗定时炸弹。
实际结果是苛刻的:单元测试不涉及银行、网络或时钟。如果你的功能只能通过添加半个应用程序来测试,那么问题就是代码耦合。该测试免费为您提供架构诊断。
第四步:决定如何处理外部依赖
数据库、第三方 API、支付网关、电子邮件服务。每个真正的应用程序都依赖于它之外的事物。如何在测试中处理它们是一个结构性决定。
有两个不好的极端。模拟一切使套件快速但不真实:您测试关于依赖项的假设,而不是依赖项。使用真实的一切使得套件忠实但缓慢且不稳定。
我捍卫的平衡:内部和外围依赖性加倍,关键边界的真正集成。 [支付网关0和持久层值得在受控环境中针对实际实现进行测试。在大多数情况下,电子邮件服务可以被模拟。
步骤 5:将测试数据视为架构的一部分
数据是导致套件下沉的看不见的部分。当数据模型发生变化时,手工组装、分散、重复的场景将成为维护的噩梦。
将场景创建集中在可重用构建器中。它不是每次测试都从头开始组装完整的订单,而是要求“有效的订单”并仅调整对案例重要的内容。这可以减少噪音,使测试可读,并保护套件免受模型更改的影响。
在处理个人数据的产品中,有一个许多人忘记的额外预防措施:切勿在测试环境中使用真实的生产数据。除了泄漏风险之外,这还直接与[LGPD1相矛盾。测试数据必须是合成的。
第 6 步:从头开始与跑步机集成
仅在编写它的人的计算机上运行的套件不能保护任何人。第六步是从一开始就将测试集成到 CI 中,而不是作为改造。
阶段结构:先驱动,快速失败;之后进行集成和端到端。定义拉取请求不进入红色套件。这个简单的规则改变了文化,因为它将测试从“可选任务”变成了交付流程的一部分。
并尽早测量执行时间。一个在没有时间控制的情况下增长的套件迟早会成为团队学会解决的问题。
没有人正式规定的步骤:维护
最后一步很少出现在脚本中:决定谁将随着时间的推移来照顾套房。测试代码会像任何系统一样老化、积累重复并进行间歇性测试。
这里的结构决策是将测试视为完成定义的一部分,并将套件健康状况视为工程指标。如果没有所有者和指标,最好的初始架构在一两年内就会退化。
按照正确的顺序、风险、级别、隔离、依赖性、数据、传送带、维护来设置测试架构不是官僚作风。这就是让你有勇气改进系统的套件和让你害怕接触它的套件之间的区别。
如果您正在构建新产品的测试或试图挽救已成为负担的套件,那么在打开编辑器之前值得先执行这些步骤。我的博客上还有其他关于质量和工程的文章,如果这是您团队中的具体难题,那么这是一次很好的对话。
另请阅读
- [自动化测试架构:需要速度的团队的快速指南2
- [回归测试:防止破坏已经有效的方法3
- [自动化测试:为什么未经测试的代码是债务4
- [软件测试周期:趋势和领导者快速指南5
- [软件性能:关于质量的真实案例教学6
- [自动化测试:架构和基础7