速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

持续集成之“测试三角形与分段构建策略原则”

  • 2011-02-17
  • 本文字数:3396 字

    阅读完需:约 11 分钟

随着软件产品新特性的不断增加,软件自动化测试用例的数量也会成倍增长。对于一些历史“悠久”的遗留系统来说,甚至会积累数以万计的自动化测试用例。如果对这样的系统进行持续集成,还要求每个开发人员都要进行本地验证的话,困难的确不小。让我们还是看看 Joe 的团队是如何解决类似问题的吧。

在《戏说Checkin Dance 》一文 中,咱们说到:Joe? 的团队实施了带有令牌的持续集成提交流程纪律。由于每个人都做本地构建进行验证后再提交,所以持续集成平台上的构建结果比较稳定,每天持续集成服务器上的构建最多只有 一两次失败(常见的原因是忘记提交某个文件而导致失败,和因本地环境配置与平台环境配置不一致而导致失败),但一般都能在30 分钟内修复。随着项目的进 行,新功能不断地增加,自动化测试用例也越积越多。由于不做任何修改,本地构建脚本就会运行所有自动化测试用例,所以本地构建的运行时间也越来越长。团队里有人开始抱怨,“每次提交代码前,运行本地构建都超过15 分钟,这样太浪费时间。我们可否把那些不太重要的测试拿出去,不再运行了?”

一、自动化测试黄金三角形

作为团队的技术负责人,Joe 把大家叫到一起,就这个问题进行了专门的讨论。

“我们不能放弃运行这些测试。”Alice 说道,“在我前一个项目中,我们就是这么做的,结果,这些花精力写的测试都作废了。”

“那是为什么呢?”?Bob 问道。

Alice 回答道:“因为并不经常运行这些测试,随着功能的修改,有些测试的逻辑就不再是正确的了。而当再次运行发现这类问题时,通常的结果就是把这个测试删掉,因为修复这个测试的工作量太大了。”

“那持续运行所有测试的话,等待的时间太长了,也是一种浪费呀。?”Bob 说道。

此时,作为团队技术负责人的 Joe 说话了。“让我们先分析一下,到底有哪些什么原因让我们的测试在这么短的时间里就变成需要这么长时间了呢?”

“功能增加的多了,测试自然就多了呗。”

“功能增加了,自动化测试数据的准备工作也多了,需要的时间当然就长了。”

“现在我们的测试中有很多地方需要测试在原地等待结果返回,所以等待时间也挺长的。”

“大家还有没有其它原因?”Joe 追问道。

大家沉默了一会儿,Bob 说道:“好象主要就这些原因吧”。

“那好吧。功能多而导致测试多这是好事儿,说明我们大家都非常重视我们的自动化测试。对于‘测试准备时间变长’这个问题可以理解,因为我们的产品越来越复杂了。对于‘结果返回的等待问题‘嘛,需要具体问题,具体分析。前几天,我看到一个‘测试黄金三角形’,讲的就是自动化测试中各类测试的应具有的比例关系,对我很有启发。我在白板上画一下吧。”于是,Joe 走到白板前,将这个测试黄金三角形画了下来,如图 1 所示。

然后,Joe 将这个图形解释了一下。原来,这个三角形讲的就是单元测试、集成测试和验收测试的关系。首先,左边向上的箭头表示,越高层次的测试维护成本越高,运行时间越长。因此,对于单个测试来说,单元测试运行最快,维护最容易,而集成测试次之,验收测试则最高。? 每类测试的面积代表着该测试的数量。现在,业界有很多种工具支持单元测试,因此它的编写及维护成本相对其它两种测试来说较低,应使用单元测试对代码做尽可能多的测试覆盖。一般来说,单元测试覆盖率达到70~80%是比较理想的状态。

接着,Joe 问了大家一个问题:“我们产品中的这些自动化测试属于哪一类测试?”

Alice 说道:“那要看你怎么定义单元测试中的这个单元。”

“根据 WikiPedia 上的定义,一个单元是指应用程序中最小可测试的部分。既然我们使用面向对象的开发语言 C++,那么单元测试的粒度应该是类中的一个方法吧。而且,通常来说,如果一个测试包括以下任何一个情形,它就不是一个单元测试:(1) 需要连接数据库;(2) 需要网络通信;(3) 需要与文件系统打交道;(4) 不能和其它单元测试同时运行;(5) 需要对环境进行一些配置(如编辑配置文件)才能运行它。”Joe 回答道。

“要是这么说的话,我们的测试中,一部分是模块集成测试,一部分是验收测试,只有一小部分算是单元测试。我们的测试集合正好是一个倒三角。”Bob 边说,边在白板上画了出来,如图 2 所示。

“既然高层次上的测试(集成测试和验收测试)维护量比较大,今后我们应该加入更多的低层次测试(单元测试),对于关键功能进行集成测试和验收测试。如果对于测试用例具有等价性的话,我们应该用低层次测试来实现。这样我们就会达到自动化测试的黄金三角状态啦。”Joe 边说边在白板上笔划着,如图 3 所示。

“我同意你说法,但是仍旧没有解决我们目前遇到的问题。如何解决我们现在本地构建时间太长的问题呢?”Alice 有点儿不耐烦地问道。

二、分阶段构建?

“这还不容易, Martin Folwer (敏捷宣言的创造者之一) 已经给出了一个解决方案,那就是两阶段构建(Secondary Build)。也就是说,我们可以把那些运行比较慢,时间比较长且基本上不会失败的自动化测试用例挑选出来,组成一个新的测试集,在第二阶段运行,可以叫做‘二级构建阶段’。剩余的测试集仍旧放在第一个阶段运行,我们可以把第一个阶段叫做‘提交构建阶段’。”Joe 回答道。

“那什么时间运行这两个阶段的构建呢?”Bob 问道。

“提交阶段构建当然就是在我们每个人提交之后就运行啦。而且在我们提交之前,作为本地验证集合,在我们开发环境上也要运行同样的提交构建。一般来说,本地构建和提交构建最好都在五分钟内完成,最长也不要超过十分钟,否则开发人员就不愿意花时间做频繁地代码提交啦。另外,一旦提交阶段构建成功以后,就马上自动触 发第二阶段构建。而我们开发人员在持续集成服务器上的提交阶段构建成功以后,就可以继续进行其它的工作啦。”Joe 说道,“我们原来的六步提交图就变成这 个样子了。”说着,Joe 拿起白板笔就画了出来,如图4 所示。

“不对,这里有问题!持续集成强调尽早反馈。如果把测试分成两个阶段了,那反馈周期不是加长了 吗?”Bob 反驳道。

Joe 点点头,说道:“你说的没有错。但是,根据我们现有的软硬件资源条件,我们目前还无法通过增加资源的方式来缩短所有测试运行的时间。所以我们必须在质量与速度之前做出平衡。这也是我为什么要把那些不易出错的自动化测试集合放在第二阶段构建的原因,这样可以降低但不能完全解除第二阶段构建失败的风险。所以, 这也要求我们大家当第二阶段构建失败时,也要找人尽快把它解决,并且把相关的测试再次放回提交测试阶段中运行,或者在提交测试阶段加入新的测试来补充。” ?

Alice 此时插话,问道:“既然第二阶段构建不常失败,为什么我们不定时运行它,比如每天晚上运行一次呢?这样不是更节省资源吗?另外,如果第二阶段构建运行得慢,那它不是一直都落后吗?”

“因为每次提交阶段构建成功以后就触发第二阶段构建,这样无论如何都比每天晚上运行一次的更多的反馈。因为每天晚上运行一次的话,如果出了问题,我们只能在第二天早上才能发现。对于你的第二个问题,我画一张图来解释。”Joe 找了一张大白纸,在上面开始画了起来。

一会儿功夫,几个示意图就画好了。看到这几个示意图以后,大家恍然大悟。如图 5 所示。从图中我们可以看到:

  1. 当版本 123 的第二阶段构建被触发并正在运行,Alice 又提交了一次,触发了版本 124 的提交构建;
  2. 当版本 124 的提交构建完成之后,由于版本 123 的第二阶段构建仍在运行,所以不再触发第二阶段构建;
  3. 当版本 125 的提交构建完成时,版本 123 的第二阶段构建仍旧在运行,所以也不触发第二阶段构建;
  4. 当版本 126 提交构建正在运行时,版本 123 的第二阶段构建刚完成,此时由于版本 125 的提交阶段构建是一个最近 成功完成的提交构建,所以持续集成服务器就会启动该版本的第二阶段构建,而忽略版本 124 的提交构建。

“那根据我们持续集成纪律,谁的提交让构建失败,就由谁来修复。如果版本 125 的第二阶段构建失败了,就包括版本 124 和 125 两次提交的变更,由谁来修复呢??”Bob 接着问道。

“这个好办,由这两个提交人一起负责修复。如果想确切找到谁的提交有问题,还可以手动触发版本 124 的第二次构建。假如构建成功,说明版本 125 有问题,假如构建失败,说明问题在版本 124 就引入了。”Alice 抢着说道。

讨论到这里,团队成员都达成了共识,(1) 开始加强单元测试的力度;(2) 在反馈速度和反馈质量之间做出折衷,使用二级构建构建的方式。

整个产品的开发非常顺利,马上就要进行版本发布了。团队还会遇到什么问题呢?他们是如何解决的呢?请听下回分解。?

2011-02-17 02:325252
用户头像

发布了 100 篇内容, 共 21.9 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

牛马真的沉默了,入职第一天就干活

秃头小帅oi

2024深圳国际数字能源展览会

AIOTE智博会

能源展 数字能源展 深圳能源展

大厂B端/G端数据可视化项目如何做设计评审

京东科技开发者

TiKV的Raft逻辑梳理总结

TiDB 社区干货传送门

TiKV 底层架构

9 个适用于小型企业的顶级API管理解决方案

幂简集成

API API接口管理 API接口工具 API管理

rbenv:Ruby 多版本管理利器

不在线第一只蜗牛

ruby 后端 项目开发

主流国产数据库的HTAP实现,TiDB实现的最早并应用的最深

TiDB 社区干货传送门

数据库架构设计

深入解析:Netty 与 Dubbo 的关系与应用

Liam

程序员 dubbo 后端 Netty 分布式系统

一图解锁 | 运维管理到工具体系的建设逻辑

嘉为蓝鲸

运维管理 运维工具

反射API与AOP:打造可插拔的插件式架构

技术冰糖葫芦

API Explorer API 文档 API 性能测试

TiDB Server 的优雅下线

TiDB 社区干货传送门

数据库连接

京东面试:SpringBoot同时可以处理多少请求?

王磊

面向AI的开发:从大模型(LLM)、检索增强生成(RAG)到智能体(Agent)的应用

京东科技开发者

大模型在蓝鲸运维体系应用——蓝鲸运维开发智能助手

嘉为蓝鲸

运维 大模型 运维管理

抖音商品API接口:开启电商自动化和数据洞察之门

Noah

云+AI,火山引擎助力泛互联网行业创新和增长

新消费日报

AI功能探测,TiDB Vector对比PG Vector

TiDB 社区干货传送门

版本测评 性能测评 7.x 实践

听说京东618裁员没?上午还在赶需求,下午就开会通知被裁了~

王中阳Go

Go 面试 微服务 后端 Go进阶

数字孪生智慧工厂解决方案——打造绿色、透明重卡超级工厂

图扑物联

工业物联网 组态软件 数字孪生 web组态 智慧工厂

看不懂正则表达式?试试可视化工具吧!

京东科技开发者

ITSM新用法揭秘:构建科技公司售后服务管理体系

嘉为蓝鲸

运维 ITSM 流程管理

TiDB 的平面文件与数据体积

TiDB 社区干货传送门

管理与运维

长江云 IPTV 融合业务 0 改造平滑迁移上云,《面向 AIGC 的数智广电新质生产力构建白皮书》开放下载

Baidu AICLOUD

vmware 专有云 IPTV

2024年安全生产月资料合集,抓紧保存!

草料二维码

资料分享 安全生产月

鸿蒙HarmonyOS实战-Stage模型(应用上下文Context)

EquatorCoco

鸿蒙 HarmonyOS

一键自动化博客发布工具,用过的人都说好(公众号篇)

程序那些事

工具 程序那些事 自动发布

TiDB 如何利用 Copilot 优化数据库操作,提升用户体验与内部效率?

TiDB 社区干货传送门

小冰携手火山引擎,让 AI 从崭露头角到落地生根

新消费日报

25更敢为 | TATA木门25周年庆典盛大启幕 探索家居品质生活新静界

Geek_2d6073

你还在用工单系统的思维建设ITSM吗?

嘉为蓝鲸

ITSM 运维管理 平台化

win版Iperius Backup Full (数据备份工具) v8.1.7 中文激活版

iMac小白

持续集成之“测试三角形与分段构建策略原则”_Java_乔梁_InfoQ精选文章