zoukankan      html  css  js  c++  java
  • 业务团队如何高效实施自动化测试

    摘要

    美团酒旅的终端研发团队,在2017年实施了大规模的自动化测试。酒旅的终端研发团队负责美团在住宿、境内度假、大交通方向的业务研发工作,是一支面向业务的平台型团队。

    由于其业务属性,客户端一直面临着业务需求压力大、业务需求迭代演进迅速的挑战。这样团队是否适合实施自动化测试?是否需要付出高额的成本?是否能够获得足够的收益?

    下面由我来分享酒旅这次自动化实践的主要历程,相信一定能够给各位朋友带来帮助。

    作者简介

    梁士兴,2009年毕业于北京航空航天大学。毕业后在IBM中国研发中心工作了5年。2014年7月份加入到美团大众点评,现职位为技术研究员。

    作为美团酒旅基础服务平台负责人,经历了美团客户端业务架构演变的全部过程,因而对客户端的业务架构有了进一步的理解和思考,愿意与大家进行分享。

    业务团队是否应该实施自动化测试

    按照固有的思维模式,业务团队通常面临业务压力大、需求迭代频繁等诸多痛点。业务压力大,意味开发自动化测试程序的人力成本是个巨大的挑战;

    而需求迭代频繁,则意味着自动化测试的稳定性很难得到保障。这是否意味着业务团队无法,或者很难实施自动化测试呢?

    美团点评的酒旅终端团队,是典型的业务型团队。负责美团酒旅在住宿、境内度假、大交通方面的业务建设。

    酒旅的终端团队在2017年实施了大规模的自动化测试建设,因而在这一领域积累了不少经验和教训。

    我希望从团队实际遇到的困难与挑战入手,结合自动化测试的意义,帮助大家决策是否要实施自动化测试。

    业务团队面临的困难和挑战

    酒旅终端团队的痛点:

    历史需求时间跨度长,质量保障困难:时间跨度最长的超过三年,一些细节包括产品、开发、QA都不能很好的解释清楚

    尽管开发团队和QA同学都尽力去提升产品研发质量,但是仍然故障不断。

    苹果封杀热补技术:

    由于苹果与年初禁用了类似JSPatch的热补技术,“出现问题线上修复”的质量保证手段也不复存在。

    业务对开发效率提出更高的要求

    产品经理对研发团队的诉求概括起来通常只有两点:

    能不能多做几个需求?

    能不能早一点上线,最好明天就上?

    如果认真的对待这两个问题,本质上是业务团队在研发效率和迭代频率方面,对研发团队提出了更高的要求。

    综上所述,酒旅终端研发团队实际上面临的挑战就是:

    需要更好的质量保障手段,包括保障的效果(少出bug)和时机(上线前暴露bug);

    需要更高的研发效率和产品迭代频率。一个字,快!

    自动化测试的意义

    软件测试的定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程^1。

    自动化测试是使用软件工具和既定程序,对软件所进行的测试活动。

    对于前面提到,团队面临的第一个困难—即历史需求时间跨度长,如果有自动化测试约束,则其演变一定是一个受控的过程。这恰恰说明了实施自动化测试有非常重要的意义。

    团队面临的第二个困难,相对于热补技术这种事后补救技术,自动化测试才是更根本性的质量保障手段。

    年初有篇文章曾经发起过讨论,硅谷的互联网公司并不热衷于热补这类“黑科技”,而是更多关注利用自动化测试技术,让应用在上线之前就有更好的质量保障。

    第三个困难,需要提升研发效率和迭代频率。表面上看,似乎和自动化测试并没有太明显的关系。

    但随着我们的深入思考,发现了一个奇妙的结论:自动化测试是提升迭代效率的关键,也是提升研发效率的有效手段。见图1

    图1 酒旅迭代周期时间分配分析

    从上图可以看到,每个迭代周期中,开发时间与测试时间的比例达到5:4。而回归测试时间占据了测试时间的50%。自动化测试手段可以大幅缩减回归测试的时间成本,因此可以大幅提高迭代的频率!

    如何实施自动化测试

    明确了自动化测试的意义,下一步应讨论如何实施自动化测试。作为团队的重要技术项目,我们需要制定明确的目标。

    如何评估自动化测试的收益

    评估自动化测试的收益,需要明确短期和长期目标的设定。从实际收益来看,则需要明确“能否测出 bug”、“测试用例维护成本”、“减少了多少手工测试成本”。

    覆盖率指标则被当做过程管理的抓手,包括测试用例的覆盖率和代码执行的覆盖率。

    目标:

    短期目标:消灭SA级别的线上故障

    长期目标:减少75%的线上故障;发版频率从月提高到周

    收益衡量方法

    Bug的测出率(能不能测出来bug)

    测试用例的失效率(测试用例的维护成本高不高)

    减少了多少手工测试时间

    过程指标:

    测试用例覆盖率(开发了多少自动化测试用例)

    测试的执行覆盖率(代码行覆盖率、代码分支覆盖率)

    明确了上面这些指标,我们在实施自动化测试的时候,就需要有意识的收集这部分的数据,用来评估自动化测试带来的实际价值。

    自动化测试的方法选型依据

    明确目标和衡量方法之后,我们需要进行方法选型。Google曾经在《Google
    测试之道》中介绍过,合理测试包括单元测试、集成测试、UI测试(见下图),其占比大概为7:2:1。

    然而,从我们设定的收益衡量方法来看,这并非收益最大的做法。占比最高(70%)的单元测试,并不能测出多少 Bug。

    根据我们的经验,以用户视角进行测试,更容易发现 Bug。因此,我们需要基于实际的业务形态,选择对投入产出比最高的方案。首先我们看一下酒旅的业务形态,见下图:

    其主要包含两种页面类型:信息展示型页面和交互逻辑型页面。两种页面的关注点差异很大:信息展示型通常只是将后端 API
    返回的数据进行“简单”的处理,并最终绘制在屏幕上。

    其关注重点在于展示是否正确(UI控件的布局,文字截断、折行,等等)。

    交互逻辑型页面重点关注的是用户操作带来的逻辑处理,需要进行端到端的测试,即用户操作产生了对服务端 API 的请求。

    显然,这两种类型页面的测试关注点并不相同,因而技术选型上也会有所差异。我们的技术选型方案如图所示:

    对于交互逻辑型页面,我们选择了“面向UI接口”的集成测试方案。这种方案主要解决细粒度的程序逻辑校验,这类页面占比较低(约20%)。

    但是意义重大,一旦出现 Bug,很有可能是较严重的故障。因此对这一类页面的测试也显得尤为重要。

    对于信息展示型页面,我们选取了UI截屏测试的方案,可以进行像素级别的展示结果校对。截屏测试方案可以覆盖大约80%的客户端页面,同时覆盖成本也较低。

    任何一个自动化测试的选型都会遵循以下的步骤:

    设置上下文状态(数据打桩、全局初始化)

    模拟用户行为

    校验执行结果

    下面我们就对信息展示型和交互逻辑型页面,使用自动化测试的三部曲的套路,实施测试。

    交互逻辑型页面的测试方法

    对于交互逻辑型的页面,测试的重点是逻辑细节,我们选取对 ViewModel 进行测试。

    这里有一个背景,我们在两年前就开始积极实践 MVVM(Model-View-View-Model) 和 FRP(Fuctional Reactive
    Programming)。

    MVVM 带给我们最大的好处就在于自动化测试。

    当然,MVVM 只是使得测试变得更容易,但并不是实施自动化测试的必要条件。传统的 MVC 模式,同样可以进行细粒度的代码逻辑测试。

    如图所示,基于 MVVM 或 MVP 的设计模式,测试会变得更容易。测试用例模拟视图,访问 ViewModel 或
    Presenter,对业务逻辑进行验证,既可以校验应用的状态,也可以校验提交的后台服务器的数据(参数)。

    //1. 设置测试数据(打桩)

    [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request {

    return [request.URL.path containsString: @"替换URL的路径"]; }
    withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {

    NSData *data = 要返回的数据 OHHTTPStubsResponse *fakeResponse =
    [OHHTTPStubsResponse responseWithData:data statusCode:200 headers:@{@"Content-
    Type" : @"application/json"}];

    return fakeResponse; }]

    //2. 模拟用户行为

    LoginViewModel* vm = [[LoginViewModel alloc] init];

    //模拟输入用户名、密码vm.userID = XXXX vm.password = XXXX//执行登录动作[vm.loginCommand
    execute:nil]

    //3. 校验登录结果

    [vm.loginCommand.executionSignals.flatten subscribeNext:^(id x) {
    expect(x).equal(@"LoginSuccess"); done(); }];

    信息展示型页面的测试方法

    我们选择截屏测试方案对信息展示型页面进行测试。想要使用截屏测试方案有一个前提:就是除掉程序代码的因素,每次截屏都需要有唯一的结果。

    这就对应了自动化测试三部曲的第一步,“设置上下文状态(数据打桩、全局初始化)”。

    通常情况,信息展示型页面总是需要展示后台API返回的数据,并且可能展示一些和用户状态相关的内容。

    比如,用户名、用户设备定位信息(坐标、地图)、系统日期与时间,等等。

    因此,在实施截屏测试方案时,第一步需要设置许多状态,比如对后台API的打桩和 Mock。

    这里建议将 Mock 代码进行一些封装沉淀,因为它们很大概率会被其他 Case 复用。

    第二步,模拟用户操作。信息展示型页面的典型操作通常是加载->展示,和滚动一屏->展示。这里我们选择了 KIF 框架模拟用户行为,滚屏操作十分容易。

    第三步,进行截屏或图片比对。这里我们选用了 Facebook 开源的框架FBSnapShoot。代码如下:

    //测试用例继承于FBSnapshotTestCase

    //1. 打桩 (与交互逻辑型页面相同,不在赘述)

    //2. 获取需要比对的视图

    UIView* view = 获取需要比对的视图

    //3. 截屏比较

    FBSnapshotVerifyView(view, nil);

    是不是简单的有些不可思议?

    未来展望

    针对不同的业务类型,我们同时选择UI截屏和UI接口集成测试的方案。使用这两种方案仍都有较大的效率提升空间:

    UI截屏方案的 Case 失效率较高。我们需要用工具化、平台化的方法提升Case维护效率。

    自测场景:集中展示新需求的UI截屏,并且覆盖主流机型的全部分辨率。通过工具批量确认截图的内容是否这确,可以显著提升自测的效率和覆盖率。

    Case测试失败场景:当 Case 测试失败时,集中展示全部执行失败的Case。如果确实有 Bug,就点击“报Bug”按钮;否则点击“更新截图”按钮。

    新设备支持:当出现新的设备,比如 iPhone X,我们可以集中运行全部的截屏测试用例,一次性得到所有的截图。这比手工跑一遍人工测试要高效的多

    UI接口集成测试开发成本较高。我们选取的业务场景,对质量有更高的要求,因此投入更多的人力实施自动化测试是符合投入产出比的。

    针对这种场景,我们建议通过改进框架提高复用,提升校验环节的效率。

    ————————————————

    版权声明:本文为CSDN博主「技术 · 杂谈」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/GitChat/article/details/78598896

    来霍格沃兹测试开发学社,学习更多软件测试与测试开发的进阶技术,知识点涵盖web自动化测试 app自动化测试、接口自动化测试、测试框架、性能测试、安全测试、持续集成/持续交付/DevOps,测试左移、测试右移、精准测试、测试平台开发、测试管理等内容,课程技术涵盖bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相关技术,全面提升测试开发工程师的技术实力
    QQ交流群:484590337
    公众号 TestingStudio
    点击获取更多信息

  • 相关阅读:
    启动容器失败:endpoint with name cop already exists in network host.
    docker定时任务执行脚本报错:the input device is not a TTY
    期末总结
    云图学习
    豆瓣top250
    爬取学习
    爬取图片
    爬取学习bs4
    爬取学习 屠戮盗版天堂
    爬取学习
  • 原文地址:https://www.cnblogs.com/hogwarts/p/15825139.html
Copyright © 2011-2022 走看看