实践者的 DevOps 之路(4. 自动化测试)

之前的几篇文章中我们谈到了 DevOps 的分支模型,持续集成,而这次我会说一些 DevOps 中自动化测试的相关话题。

DevOps 一项核心的优势在于能够加快产品开发-上线-反馈的循环周期,用每一个更小,更快速的迭代验证,提升产品的价值。但是在一个如此快速的过程中如何保证产品的质量与稳定性呢?自动化测试在其中扮演了相当重要的角色。

WHY

实践者的 DevOps 之路(3. 持续集成 CI) 的文章中谈到了一个典型 CI 流程应该包含的步骤,其中最重要的一个环节就是自动化测试。之所以自动化测试如此重要,是因为它不仅提供了快速迭代的质量保障,也为高速行驶的 DevOps 列车安装了一道安全闸。在一些交付质量较差,线上 bug 不断的系统中,我们会发现大多存在着以下的这些问题:

  • 大量的手工测试,复杂的测试用例,但是仍会遗漏重要的业务场景

  • 无法进行有效的回归测试,上线的新功能往往引发老功能的 bug

  • 开发人员本地测试不充分,导致开发与测试之间过多的返工,进而降低整个迭代的交付质量

一些开发团队采取的解决方法无非是两种,增加开发人员与测试用例的数量,希望用一张更大的「网」来捕获那些 bug,可惜「网」越大,洞也越多。而另一种解决方案则是增加每个迭代的时间周期,从一周,两周变为一个月,并且让开发批量提交代码到测试环境,进行集中的测试。这样的结果就是退化为了一个小的瀑布模型,虽然从表面上看交付的「吞吐量」提升了,但是交付质量并没有改变,反而产品的反馈时间大大延迟了。

思考一下这个问题的本质,我们所需要的是一种快速,高效的质量反馈机制,尽可能少的人工干预,每一次代码的变更都应该触发这种检查机制,一旦发现问题就会通知我们,而我们也应该第一时间去修复那些问题。

自动化测试能够很好的满足以上这些需求,通过使用 Jenkins 这种 CI 集成工具,能够非常方便的运行各个层面的测试代码,在进入手工测试阶段之前就最大限度的发现缺陷。

但是既然自动化测试是如此好的一项技术实践,那么为什么没有成为每个项目的必要组成部分呢?

How

实际项目中无法真正用好自动化测试的原因很多,总结下来无非以下几种:

  • 不重视测试技术,大量依赖手工测试,对自动化测试的技术与理论也不够了解

  • 过于聚焦在 UI 测试这类繁琐,不稳定的测试场景,忽略了单元测试,接口测试这类高收益的自动化测试

  • 团队内部无法有效地推广类似单元测试这样的技术,很难从最基础的实践开始自动化测试

面对这些问题时,不妨从下面两点来思考解决的办法。

老生常谈的价值驱动

许多人对测试以及自动化测试的第一个问题往往是:“我项目中的(自动化)测试的覆盖率应该是多少?”。一般我会问他,现在他项目中的测试覆盖率是多少?答案往往是 0%。如果是 0% 的话那就很好解决,在编写新代码的过程中增加测试吧!

第二个经常被问到的问题是:“测试覆盖率需要做到 100%吗?如果不需要,那么应该做到多少?”。我的答案很简单,覆盖率并不是关键,关键是你要明白需要测试的是什么。

回到我们都熟悉的「测试金字塔」,如下图:

整个图很容易理解,越底层的测试运行速度越快,而且成本越低。反之,越往上运行速度越慢,且成本越高。所以我们应该最大限度的推行单元测试与集成(接口)测试,而有选择的使用 UI 测试。在我看来单元测试是收益最高,效果最明显的一种实践。虽然之前提及测试覆盖率并不是硬性的指标,但是在一个全新的团队推行单元测试时可以暂时设定一个覆盖率的指标,例如 70%,帮助开发人员形成编写测试用例的习惯。在实际工作中,对于那些类似 DTO 这样的纯数据对象可以不编写单元测试,因为它们不没有太高的价值,只有一些简单的 set/get 方法。同样的,对于与数据库,或是其他外部资源交互的类也可以不编写单元测试,而是把它们放到集成测试中。单元测试更加应该关注业务逻辑的实现与设计的合理性。

在集成测试与 UI 测试中价值的意义更加凸显,因为运行测试,准备数据的代价更高昂,而运行测试的时间也更长。我们应该从业务重要性,风险度的角度出发,分析每个接口与页面,从而决定是否需要编写对应的测试用例。

许多项目在推行自动化测试的初期阶段,会要求每个接口,每个页面都需要编写测试用例。带来的结果往往是付出了很大的精力与时间,但是由于 UI 变化频率,集成测试数据准备的原因,测试很不稳定,开发团队花费了大量时间在测试稳定性上,最后对于整个自动化测试丧失了信心,全盘否定。

先做好单元测试,之后在考虑价值的前提下逐渐增加接口与 UI 的测试覆盖率才是一个比较稳妥,易于推行的实践方法。

必要的技术支撑

很多团队对于测试技术的了解还是停留在 XUnit 与 Selenium 的阶段。但是这几年出现的技术已经大大提升了编写,运行测试的工作体验体验。

使用 Spock 编写的单元测试代码更少,但是更具表达力,而各种 mock 框架的引入使得单元测试可以更加关注于类与类之间的交互。Mountebank 这样的接口测试平台让接口测试不再变的繁琐,可以非常方便的使用 stub 模拟各种接口的返回结果。

TestCafe,Cypress 或是 Puppeteer 让 UI 测试变的不再像以前那样繁琐与脆弱,可以通过框架的 API 非常简单的模拟各种主流浏览器的用户行为并验证页面的响应。

容器技术与云平台的普及,也为自动化测试带来了更多的可能性。在一些项目中,我们使用容器化技术,针对每个接口测试快速的生成一个容器化的完整环境,包括各种依赖的中间件与数据库,完成测试之后即销毁容器。这样可以大大减少开发人员的负担,让他们不再把编写接口测试看成一个痛苦的付出,而是对自己工作的一张安全网,更加愿意去编写测试用例。

What

在 DevOps 中我们应该追求怎样的自动化测试?我的答案就是下面的这几点:

  • 不要盲目追求覆盖率,而是思考业务上的价值(重要性与风险)

  • 初始阶段做好单元测试,然后考虑接口测试,以及 UI 的自动化测试

  • 针对 UI 这类可能变动频繁,测试成本较高的部分,更加应该专注价值,而不是盲目的编写大量测试用例

  • 调研一些最新的测试技术,高效先进的框架往往能够为你节省大量的时间

  • 善于使用容器化技术解决测试基础套件的问题,提高测试的运行效率

  • 为开发人员创造更友好的,编写测试用例的开发环境

但也不要踏入技术万能的陷阱中,整个团队树立正确的质量内建,根因分析文化,才是自动化测试以及 DevOps 成功的关键。

相关阅读:

很不幸,自动化测试永远只能是必要非充分条件

面对疫情这样的复杂问题,有什么招呢?

DevOps关键能力之文化的力量——重磅新书预览《加速》

小说体敏捷/DevOps转型教科书

和实战经验分享

又到拼人品的时候,喜欢《猎豹行动》的朋友请赏个脸投票。

每人每天可以投3票,截止4月19日。谢谢。

关注公众号看其他原创作品

敏于思 捷于行 

坚持每周输出一篇高质量文章

觉得好看,点个“在看”或转发给朋友们,欢迎你留言

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值