【NCTS峰会回顾】中国卓越测试中心陈晓鹏:基于BDD的敏捷测试案例分享
2019年10月26日,由Testin主办的第二届NCTS中国云测试行业峰会在京召开,此次峰会以“AI+未来”为主题,汇聚来自国内外测试领域的知名专家学者、领先企业决策者、高层技术管理者、媒体从业者等,共同探讨高端云测试技术,帮助测试从业者了解最前沿行业趋势,及最新的行业实践。
会上,中国卓越测试中心负责人陈晓鹏做《基于BDD的敏捷测试案例分享》主题演讲,陈晓鹏指出,“做自动化测试,一定要跟CICD和DevOps做集成,把从Idea到实施上线到最终交付市场的整条链条打通,只有实现业务端的敏捷,自动化测试才能发挥最大的价值。”
以下为陈晓鹏演讲实录:
大家下午好,非常高兴能够参加Testin举办的NCTS中国云测试行业峰会,我在北京参加活动比较少,所以先自我介绍,我叫陈晓鹏,目前在某国际TOP3的IT咨询公司负责中国区测试业务,也就是中国卓越测试中心负责人,现在整个测试团队规模大概200人服务30-40个国内外项目。我个人的背景很简单,在测试领域工作18年多,相对来讲比较专一,期间没有换过其它领域。但是从服务的公司性质来讲,前6年是在民营企业,后12年是在外企。外企经历也非常集中,主要在埃森哲、IBM、德勤这三家全球最领先的 IT咨询公司工作。
我是2008年开始和敏捷结缘。不过在21世纪的前10年CMMI在中国非常火,所以当时虽然接受过敏捷的相关培训,但总觉得敏捷在中国落地有点难,毕竟当时是CMMI的天下。不过2010年之后敏捷在中国却发展得红红火火。2013年的时候,我在IBM开始接触 DevOps,然后一直在中国推广DevOps。我记得第一次做DevOps的讲座应该是2013年在深圳科技园,当时很多人连DevOps如何发音、是什么都不知道。不过后来DevOps也发展很快。到如今敏捷也好、DevOps也好,已经在中国如火如荼的发展,每个人都耳熟能详。
现在如果谈敏捷、谈DevOps,大家可以在网上搜索到很多很多介绍它们的书籍和资料,但是大家有没有在网上搜索过关于敏捷测试的书呢?据我所知,现在市面只有两本比较出名的专门谈敏捷测试的书,它们出自同一个美国女性敏捷专家Lisa Crispin。她这两本书是姐妹篇,已经被中国的译者翻译成中文出版。除此之外没有太多其它敏捷测试相关的书籍了,所以我在2015年开始专门研究敏捷测试这样一个话题。本来我想在今天下午去分享敏捷测试方法论体系的,但是我看大会上都想听落地的东西,所以今天下午我给大家带来了一个实实在在的敏捷测试相关的落地案例分享。
这个项目的客户是一家娱乐公司,我们在2017年和他们做接触,客户已经有了一套会员管理系统,但是该系统比较旧,技术比较落后,但客户非常有想法也非常激进,他对我们说需要用业界最新的技术、最好的方法、最先进的理念来开发一套新的会员管理系统,这是当时客户的目标。另外一个客户的目标是希望在半年内把项目上线,所以这是当时客户给我们的任务。
我们如何应对呢?通过对项目的风险分析后,我们发现挑战在于三方面内容,第一是技术方面,客户说要采用新的IT技术,那么新的IT技术势必会带来很大的技术风险。新的技术到底成熟不成熟,有没有相应的资源懂这些技术,这是一个很大的风险;第二是进度非常紧而质量要求很高,需要在半年内上线所有的功能,把老系统替换掉,用新系统做承接。同时,因为会员管理系统涉及到会员资金管理,大家知道如果系统一旦涉及到金额算错或者有问题,那势必带来非常大的负面影响;第三是采用敏捷测试Scrum加BDD开发模式来开发,在2016年这样的开发模式还处于很多人在尝试但还不是很成熟的状态。
所以,我们当时组成了项目组,大概规模是50人左右,分成5个Scrum Team,每个Team大概8-9人的规模。其中每个Team包含两个BA,这两个BA在客户的香港办公室驻场,和客户近距离沟通,获取客户需求。剩下6个人都在广州远程,有5个人是开发,1个人负责功能测试。除此之外还有两个Share的测试开发工程师是在不同Scurm Team之间共享的,所以整个项目是40-50人的规模。这个敏捷团队其实属于分布式的,因为有香港团队还有大陆团队,而且也包含多个Scrum Team。
这个项目的技术架构底层采用了亚马逊AWS云,上面是mongoDB数据库,再往上采用容器技术和微服务架构,然后通过暴露的RestfulAPI给到前端,前端用Angular JS来实现,这是技术层的介绍。同时在开发模式上引用了两个敏捷实践:一个是Scrum,Scrum大家听了很多,很多人也都在用Scrum;另外一个是BDD行为驱动开发。这是另一种敏捷实践,它和Scrum不冲突,而且还可以融合在一起,这就是当时的情况。
从整个项目的技术特点和开发特点,它们会对测试会带来四个风险:第一个风险是技术风险。在2017年初,很多测试人员都不具备云计算和微服务的知识,在这样一个技术平台下要做测试的话,如何保证在新技术下能够确保质量是第一个挑战;第二个挑战是进度风险,计划整个项目在半年完成上线,同时两周一次的迭代节奏是非常快的,大家想想两周时间要有开发还要有测试,节奏怎样配合确实是非常大的挑战;第三是质量风险,刚才提到因为系统当中涉及到金额信息,如果计算错误会带来很大的负面影响,所以在质量上也有很大的压力;第四点是管理风险,在2017年Scrum大家可能比较熟悉了,但是BDD到底怎么玩其实项目也没有太多的经验,特别是对测试人员。测试人员怎么融合在整个敏捷的流程里面其实是很大的挑战。
那么,如何面对这四大挑战呢?我们当时总结了测试难点后经过分析和寻找对策,最后把它归纳成两个策略:一个是自动化测试,我称之为倚天剑;另一个是持续集成,我称之为屠龙刀。这两招在现在看来可能不算太新的亮点,但在3年前还算蛮新的一次尝试了。
关于自动化测试,很多人会讲这没有什么特别的,因为我在项目也在用自动化测试啊。那到底有什么区别呢?我这里讲的自动化测试是分层自动化测试的概念,分层自动化是最近这几年测试的一个流行趋势。何谓分层自动化?就是指我们做自动化测试不能一直只是往UI层的自动化测试方向发力,为什么不能这样发力呢?因为UI层的自动化比较脆弱、不稳定,开发和维护成本比较高。前几年起,包括腾讯等很多大厂都渐渐的不再往UI自动化做投入,而是把测试精力下沉到下一个级别,比如API测试,甚至单元测试。今年上半年我和腾讯手机管家的测试负责人一起聊天,手机管家自动化测试的UI测试只占不到20%,大部分是通过API测试来保证的。可以看到,分层自动化已经是一个趋势了。无论从风险降低程度,从成本节省程度来讲,都应该这么做。所以,在分层自动化这部分,我们当时想的是如何把UI层,API层和单元测试层都覆盖来减少风险。
关于持续集成,这里我为什么没有强调DevOps?因为当时在这个项目里Ops运维侧不由我们这边控制,是客户管控的,所以我们没有办法做到端到端闭环的环境。当时我们只是覆盖到UAT,没有到运维,所以我们叫做持续集成。
我一直认为,所谓的自动化测试如果抛开CI/CD、抛开DevOps去谈,从整个项目来讲自动化测试的价值只局限于非常小的部分;做自动化测试,一定要跟CI/CD或DevOps做集成,把从Idea到实施上线到最终交付市场的整条链条打通,只有实现业务端的敏捷,自动化测试才能发挥最大的价值。
那么策略是有了但是怎么落地才是最重要的。我们的第一个方式是自动化测试,由于项目开发采用BDD方式,所以自动化框架选择上我们当然毫无疑问选择了支持BDD的框架Cucumber。其实Cucumber从我的理解上来讲并不能称之为自动化测试框架,我觉得更多的作用是能够一个所谓用自然语言编写的需求能自动翻译成自动化测试的代码框架,这是一个非常非常大的好处。如果在座各位年纪和我差不多的话,你一定会听说过有一个工具ROSE。如果开发出身的话,一定会知道做UML统一建模语言设计,那么统一建模语言设计工具ROSE在2000年左右是所有开发人员必须得学的一个工具。那个工具有一个非常大的好处,就是通过画UML图可以自动转化成代码框架。其实Cucumber就是和ROSE有异曲同工之妙,可以把自然语言的需求直接翻译成自动化测试代码框架。在这种情况下,自动化测试工程师所要做的,就是在代码框架里填写业务逻辑和验证规则就OK了。在某种意义上来讲,这能够提高我们自动化脚本的编写速度,这就是我们当时采用Cucumber框架的原因。
大家知道在用BDD开发模式时,在需求端要用一个标准化的或者说规定好的语法下来编写,这个语法我们叫做Gherkin语言,这要求所有需求都要采用一种叫GWT的方式,也就是给我什么样的场景,什么样条件下会发生什么样的一个结果。那么用GWT方式有什么好处呢?如果说我们在需求阶段如果用传统方式去做需求分析的话,一定会涉及到首先需要从业务需求转变成为系统需求,再从系统需求转变成开发需求,需求的转换过程会存在有信息传递的损失还有翻译错误的风险。我曾经做过一个项目的咨询,为某移动公司系统做缺陷分析,一年有400多个上线后缺陷,我当时是一个一个分析后去归类,发现大概有15%的缺陷是因为需求不明确导致开发理解和需求不一致。通过BDD方式是能够解决这个问题,因为通过BDD方式在整个项目里只有唯一的需求描述,你看不到还有什么所谓的业务需求、开发需求、系统需求,没有那么多需求版本了,你只有一份,无论是需求人员,开发人员,测试人员拿到的都是同一份的需求。我觉得BDD最大的好处,就是减少了项目成员对需求理解层面的差异和不一致,完美解决传统项目里所带来的需求问题。所以采用了BDD的这个Gherkin语法去描述需求,需求通过Cucumber框架翻译成自动化测试代码框架,翻译完自动化测试工程师只需要写一些业务代码逻辑就可以了。
我们当时除了集成UI自动化测试工具之外,还把API接口测试的工具集成进去了,为什么要这么做呢?其实我们想实现所谓分层自动化的能力,也就是说让框架既能支持UI层自动化,也能支持API自动化,那很多人会问UT单元测试呢?单元测试由开发人员通过Junit去实现。
总而言之,测试金字塔由三个测试层级去做覆盖。我们基于Cucumber做了大量二次开发的工作,大家会看到原始的Cucumber框架就在这里,就是这么一点的东西,我们在原始Cucumber框架上做了很多二次开发的工作,包括驱动层支持Selenium,HttpClient和Appium等,通过插件方式使得这样一个自动化平台不仅仅支持Web、API,还可以支持Mobile。
另外,在上层做封装。比如我们对元素管理,大家知道做UI的自动化最头疼的就是对象的改变,对象改变后很多时候必须要调脚本,这使我们做UI自动化的时候,脚本维护上工作量很大,因此,我们也在做很多这方面的改进。这里包括控件优化,还有封装,配置管理,数据管理等。比如,测试数据可以从数据库、表格导入;包括异常管理,出现问题以后有自动截屏,自动获取日志,将信息自动提供给开发人员。再上层集成了Jenkins和email,Jenkins可以做交付流水线编排和管理,能够使它达到每日构建能力,通过每日构建相当于不光只做UI测试的任务,可以做单元测试、API测试和UI测试三个层级。当然和邮件集成现在很多人说邮件很慢的,所以我们除了邮件还可以做更实时的短信通知,方便出问题以后马上有人做跟进。
这个框架特点有五个,第一是确保脚本稳定性大大增强,同时使用Cucumber加快自动化测试脚本的开发,缩减了开发时间,提升了效率;第二是通过封装手段,使得在写脚本的时候,不用再用Xpath方式去定位对象,这样操作很慢,我们会用更简便的识别方式去实现,使得我写脚本时候可以大大提速;第三是易读性,Cucumber大家知道用GWT语法写需求,这个无论开发人员也好,测试人员也好,甚至业务人员都能很容易读懂你的脚本;第四是易扩展,可以支持APP,WEB;第五是易维护,它有截屏截图、日志log等来帮助开发定位。这是我们当时在自动化测试方面做的一些工作。
刚才讲到的是自动化实践,但是自动化测试或者说测试如何融入在一个Scrum流程里,我估计在座很多同学可能都有同样的问题,测试在敏捷环境中到底怎么做?和传统测试是不是有很大变化?这里我给一个图,这个图相对来讲比较简单,但我们为了这个流程图足足花了两个月的时间才摸索出来,是实实在在通过项目实践摸索出来的。
如果大家了解Scrum,我们在每一个Sprint开始时,肯定会有迭代计划会,在计划会的时候,所有的相关人员都需要参加,无论是BA,行业SME,开发测试人员都要参加。参加完这个计划会后,会确认本次计划会做哪些用户故事。确认用户故事后,开发人员会进行开发构建和单元测试。测试人员做什么呢?测试人员会做ET,探索式测试。测试开发工程师做什么呢?首先会看本次用户故事是否能够做自动化测试,如果不行的话就停止,如果可以的话就需要做自动化测试准备。
其中大家看到自动化测试任务进度条被迭代结束时间线分成两边,也就是自动化测试任务跨了两个迭代。自动化测试任务和其它任务比起来偏后了。为什么会偏后?因为我们当时摸索出来一个经验,就是自动化测试会在第二周星期三开始才真正做自动化脚本开发。为什么会这样呢?因为我们当时发现,在最开始做自动化脚本开发的时候,因为那时开发人员还没有想好想法,在开发过程中会看到界面变来变去,前端非常不稳定,那么这个时候你做脚本开发的时候,你会发现需要跟着经常调整,这种情况下会浪费自动化工程师的很大精力。所以我们当时是等到相对稳定的时候再去做自动化脚本的开发,这就是为什么会在第二周的周二或者周三开始做脚本的开发。而自动化测试任务的完成就要到下一个迭代的第一周周三左右的时间了,这就是为什么自动化测试任务跨了两个迭代。
在座可能有些人会问本次迭代自动化测试没有完成那怎么保证质量?因为本次Sprint的质量会有这个功能测试人员通过做探索式测试来保证,而本次之前的Sprint质量是通过执行自动化回归测试的时候去覆盖,也就是N-1的迭代质量是自动化回归搞定,第N迭代质量由探索式测试搞定,所以没有什么问题。等到N+1迭代时,会把N迭代开发好的自动化脚本加到下一次回归用例库里,又变成下一个轮回了。这是我们摸索几个Sprint以后总结出来的,是一个关键点。
刚刚讲到的是自动化测试解决方法,我们实现了分层次自动化,实现API和UI自动化。接下来我们把它融合在集成的CI/CD场景里面,这是我们CI/CD的集成场景,可以看到开发人员写完代码以后不会直接提交到代码配置库里,会在本地先做代码扫描,然后做开发的JUnit单元测试,没有问题了才把代码提交到GIT里。提交到GIT后由CI/CD流程做保障。Jenkins开始构建,Jenkins先做服务端的代码扫描,因为刚才做的是本地端的。做完服务端代码扫描,然后做Docker部署,做完部署后首先先触发Cucumber做API测试,然后再触发Cucumber做UI测试。大家想为什么有先后顺序?因为API执行效率最高,执行一个API接口的测试一两秒就已经能够得到结果了,然后跑一个UI脚本可能需要几分钟。所以一般来说我们通过先做API,API没有问题了才往UI层做自动化,如果API有问题就停止,然后去解决,跑完UI后没有问题了,再通过人工做探索式手工测试。手工测试如果发现问题,那么就提交Bug,然后回到前面开发人员去修改代码和单元测试,所以这是一个持续集成的工具链,通过这样一个场景能够使得整个效率在两周之内把它测试完,而且两周之内确实能够测试完,这就是整体的集成测试场景。
另外我想补充一点,有些人以为只要把工具链搭建好了就实现了DevOps,这是理解有误。我们所说的DevOps不仅仅只是一条工具链,DevOps除了工具上的实施之外还有很多方面,包括人、组织、流程,这些方面都需要做改变才能够真正实现。