2018年DevOpsDays深圳大会精彩回顾,华为云DevCloud专家和大家分享DevOps测试之道。
我讲的这个主题主要是讲DevOps测试之道,但是叫“道”,我有一个担忧,我讲完之后,大家可能会睡得很爽。所以我们讲道的时候,更重要的是结合一些实践去讲,这样可能会有一些代入感。
我也想统计一下,在座各位哪些做过专职的软件测试?真的不少,谢谢。有开发人员做过单元测试吗?好的。今天这个题就讲对了,我们就细讲一下,在一个DevOps情况下,全站的能力下,我们的测试和开发各个角色应该怎么样关注测试和关注质量?从我自己的角度。
我2008年加入华为,至今工作10年了,一直在负责华为内部和外部的基于研发和测试工具平台和能力。当前在我们华为云的软件开发服务DevCloud这边负责整个云测的产品交付和解决方案,以及整个产品本身的质量,都在我这边负责。
我讲一下2008年到2018年,我们从工具角度研发来讲经历了哪些。我2008年刚刚入职的时候,我们做的工具更多是CS架构,用户去使用我们的工具,都是要去装一个客户端。我当时就去做基于视窗的客户端。那个时候我们的一个项目的立项,就是在年初做一个立项,就会把内部一些需求全部收集到,包括一些用户的反馈,我们把需求做了全年的排序,到年终发布产品给用户,两个月之后出一个补丁,年底出一个正式的版本。当时版本交付的节奏还是比较慢的,但是对质量要求比较强。因为我的版本上来之后,补丁要定两个月,如果用户在这个时间点发现问题,对不起只能等两个月,这时候用户不接受,所以我们要保证质量稳定。在2008年到2011年,我们的产品逐渐向敏捷方向发展,这时有一部分研发平台工具已经陆陆续续转到云上去了,一些测试类的工具也要转,做得敏捷岛编程,强制把一些实践上来了。以前是半年、两个月发一次,这次就一个月,甚至两周发一次。但是对不起,两周发一次到不了用户这边,能够形成产品化,但是还是有问题。在2011年到2014年,公司全面把我们的工具往平台化、服务化方向转型,这个时候我们的一些商业模式才发生了根本性的变化,就是说我们的需求从上云的时候,用户才更加快速的介入进来,以前的工具我做的时候,每年年初接一次需求,上云之后是时刻反馈的需求,我们就是基于这个云,把一些功能快速的开发出来,和用户去商量,说这样做行吗?用户说不行,你帮我改。这样快速做迭代,交付周期一下变快了,之前是半年交付一次,现在是一周、两周,更有甚者,可能一两天我们就把功能发布出去了。商业模式下的需求上就产生了比较大的变化。小步快跑,快速试错。
需求变化了,我们的架构也发生了变化。CS的时候我们是单点的架构,后来慢慢转型到了SOA,现在云化我们做云服务的架构。第一轮敏捷升级,我们把业务部门和研发部门合到一起,在DevOps微服务转型的时候,我们把运营和运维合到一起,后续各个角色怎么关注质量会有专项去讲。
求变化了,架构变化了,团队也变了,导致了我们也遗留了很多债务。这个债务里面,我们整理了一下,测试方面大概有这么几类,这全部都是比较细的债务,大概分几类。第一类主要就是人、团队和个人、各个角色对测试的意识是不同的。比如说我们的全功能团队对开发很重视,因为我们必须要交付产品,但是对测试方面不重视,这是一个现状,就是这样的。所以测试人员自己也觉得我是否发展受到了瓶颈,没有办法再基于这个方向继续发展。测试人员最开始有些专项的能力,包括行动可靠性等等,我们会写一些自动化的脚本,会做一些自动化的能力,但是在基于转型的时候,我会面临一些自动化开发的工具,对接自动化平台,种种这些事情要求我们的测试人员做一些转型,要有一定的编程能力。开发人员本身第一是质量不足,第二是如果是白盒子用例我会写,但是黑盒子我不会写,这不是技能问题,就是意识问题,也有忽视了流程敏捷价值观,人的思想停留在老的思想,还是开发做开发的事。除了人的意识之外,刚才讲到了技能意识,还有流程意识,例如过度依赖黑盒子功能测试,我们流程里面对测试的保障就是依赖黑盒子,结果测试、前端的UI测试,到这里就行了。还有迭代速度很快,测试时间留得很少,所有工作量的评估就评估开发完的事情,没有评估从开发到测试,乃至上线的时间点。还有环境本身也有问题,我们测试环境部署时间比较长,测试人员在α、β生产各个节点上面做部署,然后做验证。部署耗费了很多时间,我很恼火,我还没有做事,版本就反反复复的测试。
我们再讲测试本身要做什么,就是测试最重要的是要做什么。这里有两个关键的焦点,第一,测试就是一个质量活动,我做测试就是要保证质量,这没有任何问题,还有其他人测试不是为了质量吗?应该不是,它本身就和质量绑在一起。第二是业务价值,就是我的这个是要围绕我的业务价值去做,而不是说一个测试上来之后,就把测试相关的关系点、关联点全部搞一遍,这里可以举很多例子,例如我做一个在线线上支付的功能,最关心的肯定是安全,所以我的用例关键点就围绕安全大做文章,一定把安全保证好。我要做一个线上商城要怎么办?我的面向用户是老百姓,要让我妈妈、婆婆会用,我要关注易用性。除此之外,什么双十一、双十二抢购,还要关注性能。有些人去做这些开源社区,开元框架关心什么呢?扩展性、兼容性这些。所以瞄准了我的产品本身的业务价值,产品到底要做什么,然后去做质量关键点,到底是基于性能还是基于安全发力,制订相关的测试策略,然后落地。落地之后还要基于一些不良的效果不断的做一些反馈、循环,去校验整体的测试,达到预期结果。这就是我们的测试焦点。
这是一个非常经典的图,大家从各个地方也见到过,我们一定要从源头保障质量。这个图可能女孩子看起来有一点害怕,这是我们的BUG,很形象,这个东西就是很讨厌。如果是在我们没有编码之前,在设计阶段就把这个BUG发现解决,那么它的成本是最低的,如果要是到了生态环境再发现,那么各个环节的投入比重是越来越高的。但是传统的测试一般会关心发现问题,例如黑盒子测试里面有哪些问题,不会关心有什么拦截手段,其实这里有一些实践。例如我怎么样通过质量管控来保障我在设计阶段、需求分析阶段就能够拦截一些问题,这都有一些实践。例如完整的用户需求的描述需求,我们的测试人员是从需求设计开始入手,写需求测试实际用例,还有一点比较重要,我们不仅仅是瞄准功能需求,这很好对齐,影响大家架构重构的很多是性能问题,为什么侯凡专题去讲性能?我们的性能在生产环境发现之后,大家是否想完了,这个东西上不去了,要改架构,成本非常高。所以我们早期就拉架构师做性能建模分析等等,这是比较重要的。还有所有质量的活动不应该做成专题,我开发就是开发,开发之后交给测试团队,反正他们会有专题保障。现在DevOps更强调是把质量测试过程给打散,放到开发每一个环节,让全员参与进来。当然,基于这个我们作到了各个环节自动化,否则大家都不愿意参与。这就是自动化最基本的要求。
接下来我们讲自动化本身。这个图是一个非常有名的自动化金字塔图,我们基于DevOps,金字塔上面还有一些解读,例如手工测试等等。这个金字塔本身就是每一个环节的自动化能力和投入,在最底层单元测试方面,我们要做得足够好,这个金字塔不代表我的测试用例的数量,例如我单元测试写一千个用例,我更关心单元测试的质量。例如我们有一个非常重要的模块,我要保证重要模块对应的复合率要达到,重要的用户进来的分支要达到分支的覆盖。所以基于这个,单元测试不是在用例的数量上,大家一定要关心它本身的质量。在金字塔越底层做的事情,发现问题解决成本越低。而越向上一层,解决成本越高,效率也会越低。例如在界面测试发现了问题,我的定位要从界面到网络、模块A、模块B等等,会拉很多工作人员做定位。如果在单元测试发现,就是模块本身的问题,这是比较容易理解的。里面所有基于代码、到单元测试、接口测试、界面测试、UI,还是强调自动化。做到什么结果呢?我提交一行代码,能够自动把整个测试流程走遍,我出去喝一杯咖啡之后,回来看到所有的测试结果在我眼前呈现。
接下来讲一下质量相关的点是常规安全与弹性安全,它与传统观点是一个冲击。我们常规的设想,是哪个地方不安全,我一定要把所有不安全的因素找出来,清除掉。这是我们常规的做法,也就是Safety-1的小天平,指针在绿色一边是安全,在红色一边不安全。第一个做法是把不安全的红色因素一一剔除,这是一种非常理想的方法,但实际上我们是不可能把整个系统中不安全的因子全部识别到的,有能力、架构等等复杂的原因,没有任何一个人能够说哪个地方不安全能够全部去除。所以演变出了弹性安全,就是我可能经过一些内部的折腾,反复的去把不安全的场景模拟出来,基于这种不安全场景,我们给出快速的修复方案,把它加入天平里面,如果不安全的因素进来了,我用快速应对的方案能够弥补这个不安全,对于用户来讲是不感知的,对产品来讲,它的商业目的和质量目的都可以达到,这就是我们想讲的弹性安全,即便发生了错误,能够及时快速的修复或者自己修复,达到正常工作的目的,我们也可以。所以我们在这往来有很多实践,但是这个弹性安全本身在业界有一个基于安全的实践,就是我们在搭的自己的服务的时候,有的时候会接受D-Dos攻击,一般是硬扛,能扛得住这个流量,如果达不到一个G,就可能被冲死了。现在不同,有攻击时,我直接把IP干掉,引流到新的IP。大家可能会想黑客会追随进入另外一个IP,这是有成本的的,需要10分钟的时间,结合我们的快速感知,感知到他是攻击的源头,立刻在我们这里做一些防护。你给后端人员足够的时间去准备,而你的前端又没有受到任何影响,因为我直接换了一个IP,客户可以访问,没有任何问题,这就是一个很好的实践。
接下来讲测试左移和测试右移。左移就是前移,我们有自己的测试人员和开发工程师做过白盒子用例和黑盒子用例。我们想的实践是尽量把活动向前移,也就是说突破黑盒子向前走一步,越走越好。例如BDD行为开发,我们基于这个场景直接设计出符合这个场景的用例,来匹配这个设计。契约测试本身,服务和为服务本身之间有耦合,我们可以通过契约测试解耦,以防导致问题。还有我们有一些自己的能力,来提前介入一些自测试活动。测试右移是指我们现在的测试只到了版本发布之前,测好之后出一个软件包,我们要把软件包布到生产,我们尽可能到线上运营,都要去做测试。这里也有一些实践,这个灰度测试是指在这个过程中,我们把需求特性布到线上,我们测完之后再给线上用户。还有线上拨测、主动线上监控,用户的一些行为轨迹里面发现的错误问题我们能够快速的捕捉到,主动推送给相关的责任人,让他去关注并且解决。所以线上的过程可以通过一些测试手段,不断的反馈给真正的开发人员,让他知道当前产品的整体表现,他就会快速的针对产品作出一些应对方案。
接下来我们讲一下不同时期的测试策略。刚才讲了这么多的测试活动,还讲了这么多自动化的活动,那么是否说这个团队进来的时候,哪怕一两个人,就要把整个自动化能力构建起来?其实这也是一个过程,我们先从软件的成熟周期来讲,后面会再从组织人员构成上面,我们看一下怎么构建测试自动化的能力。在软件初期探索阶段,我们的产品是一个不确定的产品,就是说它里面从前端的风格和整体的布局到后端的API都会有一些变化,而且变化比较频繁,这个时候一些自动化测试用例的写作是不太划算的,不经济的,因为你的自动化用例的生命周期比较短。而这个时间段产品的特点是小的产品,特性是可控制的,也就是那么几个测试,所以我们以手动为主,不考虑自动化,让产品能够快速识别错误点,让用户能用起来。就到了扩张阶段,用户认可我的产品,这时候有两个现象。第一是用户量指数增长,第二是我们接到的需求有呈指数量增长。这时候必须要考虑自动化。我每一次迭代的全量验证成本会越来越大,而交付的速度也会越来越快,这就是一个悖论。我们不可能每一轮上线的时候都做全部测试,这时候老的方面就需要用例去保证。所以我们引入了自动化测试能力。到提取阶段,产品已经到了需求的饱和期,产品的利益增长也到了饱和期,这时候要严格控制产品需求,可能会解决一些问题,这时候自动化用例的职责变成守护,不允许我的变动引入额外的风险点、大块的特性变动,对成熟的用户造成攻击。这是三个方向,每个不同的产品阶段有不同的测试策略。
接下来再讲一下整个团队规模对测试建设的影响。如果说我们的团队规模在5个人以下,节就是处于探索阶段,这时我们的质量活动可以仅仅局限于测试的自组织阶段,只是做一些基础类测试管理类活动,把缺陷管理起来,做一些回归。其实这部分主要是建立一个测试管理的流程和机制,并没有接触到自动化测试,因为人数在这里,团队规模在这里。随着项目的进一步扩大,有5-10人的团队规模,处于扩张阶段,这时测试工作量突然增加,可能会有专门的测试人员进来,这个测试人员就会去和开发人员进行串联,在这里做好,然后他把需求转化成自动化测试的用例,持续搭建集成,逐步演进一些测试手段。这个阶段已经开始做一些自动化的尝试,这是在自动化测试阶段。团队进一步增大,一个人可能搞不定工作量的时候,会招聘更多的测试人员,成立专门的测试团队,这个团队就从自动化测试转向测试自动化,把很多的管理工作做进来,*都会进行一些管理。在这个管理过程中,我们会做一些产品的对接,包括一些开发,实现一些自动化的整体能力,不仅仅是自动化执行了。
经过上面几个演进周期之后,我们的测试团队具备了很多的测试自动化经验,这个时候我们面向云化的转型,大家很关心的就是基于DevOps的全功能团队,我们之前转型的这些人在做什么?回到微服务的架构本身,我们有运营产品,还有SL对应的SPE,很多角色、开发、运维在这里。刚刚原有10-15人的测试专项团队做什么?面临一个比较重要的转型,我们要把测试专项能力向服务化能力转型。这时候测试专员就会在团队建站初期进行赋能,包括测试工程师搭建,早期的测试用例怎么写,我们会有一些模板放在这里,你导入就可以。后面还有针对专项的,非功能性测试的专项,我们也会进行专项能力的赋能。还有对所有团队进行测试流程的评审,包括他自己的测试策略、测试计划、自己团队的测试用例,我们都会做一些评审,再看一下整个团队里面流程上还有哪些改进的,我们的整个专项测试团队就会向服务化进行转型。所以这里是一个全圆参与的过程,如果说我在2008年做的是半年发布一次或者两个月发布一次,或者每100天发布一次,可以有专门的团队,因为我有时间。但是在10天或者每天发布一个版本的时候,就要开发和设计一起去保证。但是如果每天发布10次、100次,就要把测试过程中所有的人参与的环节全部杜绝掉,做到自动化。
我们要讲一个理念,就是测试自动化。什么叫测试自动化?刚才讲了很多自动化测试,这是测试的执行部分,例如我们把一些测试执行的人工测试手段做成自动化测试,但是测试自动化不仅仅是只是执行,还包括了从环境的获取到生成测试数据、执行自动化测试,最终生成结果。如果有问题,我会自动推给相关的人,不是自己还要提个单给谁沟通,自动提单给对应的组织解决。自动生成测试报告,测试人员直接拿到测试结果。就是这样的过程。
接下来讲一下开发人员比较关心的,我们在做服务和服务之间的交互,前后台会有交互,还有微服务的服务。团队之间一定要引入契约测试,这描述起来比较简单,它既是一种测试技术,也是一种测试规范。例如这里讲的服务A和服务B,服务A依赖服务B的结构,我们怎么做?签订一个契约,服务A基于这个Mock开发自己的业务逻辑,服务B基于测试来保证给A提供的结构是OK,最终两个可以独立上线,A和B可以做远调。包括我们生活中的制造业用得比较多,螺母和螺丝分别由A和B厂商制造,但是他们会遵循一些契约,保证螺丝的长度、宽度、对应的型号和间距都会对应标准,最终两个厂商生产的螺丝和螺母能够正常工作,严丝合缝的合在一起。这就是我们的价值。
在更细一点的实践里面还包括这几点,这一点是DevCloud的实践。我们有几个专项的试点。第一是视角,测试本身不仅仅是某个细节功能点的测试,我们要基于场景做测试用例。*而且必要的情况下,我们会有一些专门的人去把这些场景手工看一下,看是否有问题。同时也有一些特性,软件开发云就是提供的开发者一站式的云上开发,整套的工具链。所以我们追寻的DevOps下的开发实践就是狗粮文化,自己的狗粮自己吃,所以我们的所有测试活动,还有软件开发活动都在DevCloud里面,这样开发人员既是开发人员又是测试人员,他自己的思维会一直在转变,不断的打磨自己的产品,最终能够产品的精益求精。还有一种是分层自动化,我们把所有的自动化专项流程打散,放到流水线里面,在编码的环节或者再向前,我们做一些安全的微信分析,在编码过程中还要做编码检视,我们会强制触发它的。我不仅仅是只有代码,还有单元测试用例,来保证单元测试本身的用例指标。在后面的阶段,还有华为云的代码静态检查,能够在预先会预先识别代码里面的规范,包括隐含的内存,通过语音语句的分析能够找到问题,进行拦截。在部署到α、Beta测试阶段,用我们的API服务构造一些可靠性和安全的用例。在∑阶段,我们会做一些用例,包括性能和场馆测试阶段,我们会用自己的服务去发掘连续的7×24小时的用例。在生产环境的在线测试,刚才反复讲了,这里最重要的还是要把一些拨测,还有后台的主动检测手段,包括前端、后端接口的检测。以及用户业务流下面的关键分支上的日志,有异常日志我们都要记录下来,然后基于日志进行分析,这些相当于用在使用过程中也会给我们出一些质量的反馈。
这就是我们的测试不断前移的过程。这个材料主要是讲服务的团队,全功能团队会越来越多的介入到测试里面来,但是我们一些测试的专职的事情要足够做到服务化,这对我们现在的专职测试人员是有挑战的,我们以前做了很多专项活动,花费了大多的人力和成本,这些成本需要通过一些服务化的能力,我们要使用一些开源或者软件开发人员的能力,能够降低人力投入成本,能够实现自动化测试,那么我们全功能团队就可以用上了。还有性能测试、安全测试都可以慢慢向前面转移的,Chaos测试可以构造一些故障脚本,通过API方式向大家去。拨测也是一样的,做成7×24不断循环执行的过程。
讲了这么多,我做华为云的测试产品,最开始是对内部的,有很多的测试工具,做到一定程度之后,我们也积累了很多的测试经验。在这里,我们对外发布了一些我们认为比较好的实践所带来的工具,例如现在我们提供的,当前已经上线,包括DevCloud的云测和移动应用测试以及实现解决方案,能够很好的为大家创造便利性,解决问题。包括整体测试流程管理、测试的用例和需求、虚线能够双向可追溯,能够看到这个需求到底是否测试,或者是否测试错了。通过自动化的能力,例如对安卓和IOS的测试,拿一个软件包放在后台,对它进行系统化的兼容性测试,看是否有兼容性的问题,能够涵概多少用户,还有接口测试,能够涵盖接口一层的手段,还有性能测试,模拟一些大并发的场景。我们提供完全可视化的看板,能够提供测试执行的情况。
接下来都是我们的一些看板,例如这是我们的管理看板和对应的测试看板。APITest可以让开发人员投入写这种测试用例,而且是非语言类的,你可以通过鼠标加一些必要的参数进行编排,我们就能够通过这个接口把场景构造出来。如果我们的产品是微服务,可以把它导入进来,整个过程是非常简单通俗的。
性能测试也是围绕接口测试,但是会提供多种加压策略,能够是现在测试过程中我们能够对于用户的吞吐量、响应时间、负载能力,整体做一个结构分析。这就是刚才讲到的兼容测试,能够看到终端数安装是否失败,甚至一些问题失败的原因,包括系统截图等等,供大家进行问题追溯。
华为云DevCloud作为一站式云端DevOps平台,集成华为近30年研发实践和前沿理念,面向开发者提供研发工具服务,让软件开发简单高效。现支持5人以下额度范围内,可以免费使用,并且可以预约免费的产品演示和技术交流,详情查看华为云官网