正如我们所知,DevOps最近几年很风靡,很多企业正在如火如荼的推行它。然而,你可曾想过,从传统到敏捷、再到DevOps,开发模式的不断革新对测试提出了怎样的挑战?
最近我们项目在实施DevOps,因此想趁热打铁,就DevOps模式下如何做测试,谈一谈自己的认知。
DevOps有什么特征
DevOps是一系列软件开发实践,强调开发人员(Dev)和运维人员(Ops)之间的沟通合作,通过自动化流程,使得软件构建、测试、发布更加快捷、频繁和可靠。
1. DevOps强调一种文化
在很多企业中,开发和运维人员通常隶属于不同部门,有着不同的工作环境,采用不同的沟通方式,使用不同的开发或运维工具,并且有着不同的业务目标,这使得他们之间形成一道参不透的墙。
DevOps实际是一种文化上的变迁,强调开发、运维、测试等环节之间的沟通合作。意在帮助这些人向着一个共同的目标努力:尽可能为公司提供更多价值。为了支持这种合作的发生,需要在团队内部文化和企业组织文化两个层面做出努力。
2. DevOps是一种实践
所谓DevOps,就是将敏捷方法延伸到Production!
DevOps主要是为了将敏捷开发实践扩展到运维阶段,进一步完善软件构建、验证、部署、交付等流程,使得跨职能团队能够完成从设计到生产支持等各环节的工作。
3. DevOps包含一系列工具链
DevOps是一种融合了一系列基本原则和实践的方法论,并从这些实践中派生出了各种工具。这些工具体现在软件开发和交付过程的不同阶段:
- 编码:代码开发和审阅,版本控制工具、代码合并工具
- 构建:持续集成工具、构建状态统计工具
- 测试:通过测试和结果确定绩效的工具
- 打包:成品仓库、应用程序部署前暂存
- 发布:变更管理、发布审批、发布自动化
- 配置:基础架构配置和部署,基础架构即代码工具
- 监视:应用程序性能监视、最终用户体验
DevOps对测试提出了哪些挑战
刚参加工作时,我参与了某Audi系汽车电子的软件研发,采用的是传统瀑布开发模式。在整个项目生命周期中,前半部分设计和编码,后半部分用来测试。然而我在东家工作了两年,也没能等到产品交付到用户手上。直到去年,我们的软件才得以量产并投入市场。在这4年中,产品从未交到用户手上,因此无法验证它所带来的价值,也没有任何机会得到用户反馈从而适应变化。
后来,我又参与一个银行项目,我们采用敏捷的开发模式,全功能团队,开发测试并行,每2-3周就交付一个版本。但因为没有真正发布到生产环境,我们仍然无法及时得到有效的用户反馈。
现在,我们采用DevOps的优秀实践,开发和运维协同工作。每个迭代完成,或者每修复一个线上缺陷就立即部署到生产环境。这样,我们就能够迅速从用户处获得反馈并且快速做出响应。
通过参与传统、敏捷和DevOps的项目,我深深地感受到流程的改进对团队以及项目的产出和质量所带来的改变。
那么,这些改变究竟是对测试提出了什么样的挑战? 我认为有以下几点:
1. 频繁部署
在采用DevOps之后,我们能够根据项目具体情况做到每天甚至一天多次部署。在生产环境频繁部署软件,最大的挑战就是测试。以前,测试基本上都在开发阶段之后和产品上线之前完成。但现在,不再有充足的时间留给QA团队去发现问题再抛给开发团队来修复。那么,速度成了测试面临的一大挑战。
2. 自动化
DevOps强调将流程自动化,测试作为其中一个重要环节,势必要大规模实现自动化。因此测试人员的自动化编码能力正在面临极大的挑战。
3. 实践和反馈
敏捷提倡我们要拥抱变化,更多的是要适应需求的不断变化。虽然一部分功能性需求是明确又具体的,我们清楚的知道用户想要什么,也因此易于测试。然而,也有一些非功能性需求的验收标准没那么明确,比如:提高应用性能达到良好的用户体验。我们如何才能验证用户体验是否真的良好呢?仅仅通过性能指标吗?当然不是,满足指标只能说明一部分问题,唯有真实的用户数据和反馈才是可最靠的。
4. 协作
敏捷强调全功能开发团队的共同协作,但这仅仅止于开发阶段。而DevOps注重Dev、Ops和QA三个群体之间的密切协作。因此,良好的角色定位能够帮助测试人员将价值最大化。
我们是如何做测试的
Laurent曾经在Hiptest上发表了博客《Shift left and shift right: the testing Swing》,提出了一个有意思的测试矩阵,从四个维度进行分析,描述了当软件开发模式从瀑布到敏捷、再到DevOps转型时,测试该如何响应变化。
Laurent提出一个测试左移和右移的概念:
- 测试左移,就是指在开发阶段之前定义测试。
- 测试右移,就是直接在生产环境中监控,并且实时获取用户反馈。
在敏捷开发的生命周期中,我们通过每一次迭代来丰富和更新产品,以使其最大限度地符合客户对系统的需求。当时测试的关注点基本停留在开发阶段,以保证产品达到上线标准。引入DevOps之后,我们不仅要关注产品的质量是否达标,还需要使价值假设得到及时的验证。因此,我们不仅要将测试左移,在开发环境验证功能的可用性,还要进行测试右移,通过监控产品在生产环境的运作情况,来验证其价值并获得反馈,从而持续改进。基于这些理解,我在项目上做了初步的尝试并取得良好的效果。我将这些尝试和实践总结为以下几点:
1.如何保证新功能得以实现?
在开发环境,我们开发新功能,并且通过测试保证其达到产品验收标准。
首先,使用BDD(Behavior Driven Development,BDD)的方式定义用户需求,这样用特定的语言来描述用户行为,能够使各个角色(测试、开发、产品负责人、市场等)对业务价值达成一致的理解,从而使其从需求到最后的测试验证,进行高度的协作和沟通,最后交付最有价值的功能。同时,QA能够提前Review故事卡,补充验收标准。除此之外,BDD方式的用户需求可以直接指导测试,后续我会写到。
其次,采用单元测试来验证最基本的代码逻辑。在编写单元测试时,建议Dev和QA Pair工作。单元测试可以认为是编码的一部分,要对系统的代码逻辑有深入的了解,因此,Dev是最合适的人选,而QA可以帮助测试覆盖的更全面。
最后,每一个功能都要严格按照故事卡的AC(Acceptance Criteria)进行验收,并采用探索性测试方法来对新功能进行无死角测试。
2.怎样验证新功能的价值?
我们将新功能部署到生产环境以后,接下来就应该衡量业务价值是否达到预期。
验证预期的一个好方法是衡量用户的行为变化。比如:在上传图片的功能后面添加了一个预览按钮,但用户却极少用它,很可能是因为用户根本不需要这个按钮,或者按钮放在了不恰当的位置导致用户不方便使用,亦或是按钮样式不够友好,导致用户没有欲望使用它。这时候,该按钮的业务价值就没有真正达到,是时候调整一下了。
3.如何确保已有功能不被破坏?
在软件开发中,任何代码都不可能完全独立存在,一行代码的变更也有可能导致系统的全面崩溃。那么,如何保证在开发新功能的同时,已有功能不被破坏?换句话说,如何做到全面的回归测试?人力是最高成本,也有现实的局限性,比如,人手不够,重复做同样的事情人会变得烦躁,手不够快导致效率低下等。因此,自动化测试才是不二选择。
将BDD需求直接转化为自动化测试用例。每个测试用例都应该讲一个关于应用程序的故事。当一个测试用例使用一致的业务术语定义时,它的可读性会比较高,且容易自动化。与此同时,上一个迭代的用例在下一个迭代就可以迅速转化为回归测试的基线。
支持BDD的工具有很多,比如:Cucumber。简单举个例子,如图:
BA用BDD方式定义用户需求,QA Review并补充AC,然后将其编写为自动化测试脚本。如果QA的编码能力较弱,可以让Dev协助完成代码实现的部分。这也充分说明了协作的意义。
最后,也是更重要的部分,测试应该集成在CI中。每一次Build或者每天都要去执行测试,验证已有功能是否完好。这样才会对没有预期到的变化产生的问题给出快速反馈。
另外,做一些性能测试、兼容性测试、和安全性测试等等。
4.怎样验证产品的可靠性?
有时候,某些缺陷并不是源于代码的错误,而是一个不好的用户体验,或者只有当数据达到一定量时才会出现,测试人员是无法模拟这种类型的测试的,因此直接在生产环境监控变得高效又可靠。通常我们需要监控两种特性:性能和可用性。
使用工具持续获取用户数据,或者使用log持续获取性能信息。这有助于监控产品部署到生产环境后是如何正确运作的。快速启用一个功能,在生产环境实时监控验证其业务价值,获取到有效且快速的用户反馈,加之拥有持续部署的能力,我们能够在出现问题的时候快速做出反应,从而使得我们的产品更加可靠。
这里实际上融入了《QA in Production》的理念。现如今,已经有很多工具和方法支持在生产环境做测试了。篇幅太长,这里就不做详细阐述了,请参考原文。
到这里,再来回顾一下,我们的实践是否真的卓有成效。
- 用BDD的方式定义用户需求、编写测试,有益于不同角色之间的一致理解和共同协作。
- 自动化测试解决了频繁部署所带来的挑战,同时保证产品的整体功能持续得到回归和验证。
- 在线监控能有效地验证不确定需求,通过生产数据分析和预警问题的发生,并且快速获取用户反馈从而及时调整。除此之外,这一点也充分体现了Dev、QA和Ops的协作,像监控等原本只能Ops做的事,现在Dev或QA一样可以做。
写在最后
测试是一种活动,曾经我们通过它来验证产品是否达到上线标准。现在DevOps模式下,我们需要在各个阶段不断地执行测试活动,以达到产品质量的持续改进。
而QA(Tester)仅仅是一种较多进行测试活动的角色。敏捷一直强调“团队为质量负责”,测试不再是QA(Tester)的专属。DevOps模式更是对测试、尤其是自动化测试提出了更高的要求,也对QA的编码能力提出了极大的挑战。作为团队成员,每个人都有责任了解开发流程、提高测试技能,把好测试这一关。但是,测试活动作为QA(Tester)的主要职责之一,提高自动化测试技能,就是当下每个QA(Tester)最为紧急且重要的事情了。
【文章转载至 ThoughtWorks洞见 】