有赞前端质量保障体系

前言

最近一年多一直在作前端的一些测试,从小程序到店铺装修,基本都是纯前端的工做,刚开始从后端测试转为前端测试的时候,对前端东西茫然无感,并且团队内没有人作过纯前端的测试工做,只能一边踩坑一边总结经验,而后将容易出现问题的点造成体系、不断总结摸索,最终造成了目前的一套前端测试解决方案。在此,将有赞的前端质量保障体系进行总结,但愿和你们一块儿交流。css

先来全局看下有赞前端的技术架构和针对每一个不一样的层次,主要作了哪些保障质量的事情:html

有赞的 Node 技术架构分为业务层、基础框架层、通用组件和基础服务层,咱们平常比较关注的是基础框架、通用组件和业务层代码。Node 业务层作了两件事情,一是提供页面渲染的 client 层,用于和 C 端用户交互,包括样式、行为 js 等;二是提供数据服务的 server 层,用于组装后台提供的各类接口,完成面向 C 端的接口封装。前端

对于每一个不一样的层,咱们都作了一些事情来保障质量,包括:java

  • 针对整个业务层的 UI 自动化、核心接口|页面拨测;
  • 针对 client 层的 sentry 报警;
  • 针对 server 层的接口测试、业务报警;
  • 针对基础框架和通用组件的单元测试;
  • 针对通用组件变动的版本变动报警;
  • 针对线上发布的流程规范、用例维护等。

下面就来分别讲一下这几个维度的质量保障工做。linux

1、UI自动化

不少人会认为,UI 自动化维护成本高、性价比低,可是为何在有赞的前端质量保证体系中放在了最前面呢?git

前端重用户交互,单纯的接口测试、单元测试不能真实反映用户的操做路径,而且从以往的经验中总结得出,由于各类不可控因素致使的发布 A 功能而 B 功能没法使用,特别是核心简单场景的不可用时有出现,因此每次发布一个应用前,都会将此应用提供的核心功能执行一遍,那随着业务的不断积累,须要回归的测试场景也愈来愈多,致使回归的工做量巨大。为了下降人力成本,咱们亟需经过自动化手段释放劳动力,因此将核心流程回归的 UI 自动化提到了最核心地位。github

固然,UI 自动化的最大痛点确实是维护成本,为下降维护成本,咱们将页面分为组件维度、页面维度,并提供统一的包来处理公用组件、特殊页面的通用逻辑,封装通用方法等,例如初始化浏览器信息、环境选择、登陆、多网点切换、点击、输入、获取元素内容等等,业务回归用例只须要关注本身的用例操做步骤便可。web

1.框架选择

-- puppeteer[1],它是由 Chrome 维护的 Node 库,基于 DevTools 协议来驱动 chrome 或者 chromium 浏览器运行,支持 headless 和 non-headless 两种方式。官网提供了很是丰富的文档,简单易学。chrome

UI 自动化框架有不少种,包括 selenium、phantom;对比后发现 puppeteer 比较轻量,只须要增长一个 npm 包便可使用;它是基于事件驱动的方式,比 selenium 的等待轮询更妥当、性能更佳;另外,它是 chrome 原生支持,能提供全部 chrome 支持的 api,同时咱们的业务场景只须要覆盖 chrome,因此它是最好的选择。npm

-- mocha[2] + mochawesome[3],mocha 是比较主流的测试框架,支持 beforeEach、before、afterEach、after 等钩子函数,assert 断言,测试套件,用例编排等。
mochawesome 是 mocha 测试框架的第三方插件,支持生成漂亮的 html/css 报告。

js 测试框架一样有不少能够选择,mocha、ava、Jtest 等等,选择 mocha 是由于它更灵活,不少配置能够结合第三方库,好比 report 就是结合了 mochawesome 来生成好看的 html 报告;断言能够用 powser-assert 替代。

2.脚本编写

  • 封装基础库
    • 封装 pc 端、h5 端浏览器的初始化过程
    • 封装 pc 端、h5 端登陆统一处理
    • 封装页面模型和组件模型
    • 封装上传组件、日期组件、select 组件等的统一操做方法
    • 封装 input、click、hover、tap、scrollTo、hover、isElementShow、isElementExist、getElementVariable 等方法
    • 提供根据 “html 标签>>页面文字” 形式获取页面元素及操做方法的统一支持
    • 封装 baseTest,增长用例开始、结束后的统一操做
    • 封装 assert,增长断言日志记录
  • 业务用例
    • 安装基础库
    • 编排业务用例

3.执行逻辑

  • 分环境执行
    • 增长预上线环境代码变动触发、线上环境自动执行
  • 监控源码变动
    • 增长 gitlab webhook,监控开发源码合并 master 时自动在预上线环境执行
    • 增长 gitlab webhook,监控测试用例变动时自动在生产环境执行
  • 每日定时执行
    • 增长 crontab,每日定时执行线上环境

2、接口测试

接口测试主要针对于 Node 的 server 层,根据咱们的开发规范,Node 不作复杂的业务逻辑,可是须要将服务化应用提供 dubbo 接口进行一次转换,或将多个 dubbo 接口组合起来,提供一个可供 h5/小程序渲染数据的 http 接口,转化过程就带来了各类数据的获取、组合、转换,造成了新的端到端接口。这个时候单单靠服务化接口的自动化已经不能保障对上层接口的全覆盖,因此咱们针对 Node 接口也进行自动化测试。为了使用测试内部统一的测试框架,咱们经过 java 去请求 Node 提供的 http 接口,那么当用例都写好以后,该如何评判接口测试的质量?是否彻底覆盖了所有业务逻辑呢?此时就须要一个行之有效的方法来获取到测试的覆盖状况,以检查有哪些场景是接口测试中未覆盖的,作到更好的查漏补缺。

istanbul[4] 是业界比较易用的 js 覆盖率工具,它利用模块加载的钩子计算语句、行、方法和分支覆盖率,以便在执行测试用例时透明的增长覆盖率。它支持全部类型的 js 覆盖率,包括单元测试、服务端功能测试以及浏览器测试。

可是,咱们的接口用例写在 Java 代码中,经过 Http 请求的方式到达 Node 服务器,非 js 单测,也非浏览器功能测试,如何才能获取到 Node 接口的覆盖率呢?

解决办法是增长 cover 参数:--handle-sigint,经过增长 --handle-sigint 参数启动服务,当服务接收到一个 SIGINT 信号(linux 中 SIGINT 关联了 Ctrl+C),会通知 istanbul 生成覆盖率。这个命令很是适合咱们,而且所以造成了咱们接口覆盖率的一个模型:

1. istanbule --handle-sigint 启动服务
2. 执行测试用例
3. 发送 SIGINT结束istanbule,获得覆盖率
复制代码

最终,解决了咱们的 Node 接口覆盖率问题,并经过 jenkins 持续集成来自动构建

固然,在获取覆盖率的时候有需求文件是不须要统计的,能够经过在根路径下增长 .istanbule.yml 文件的方式,来排除或者指定须要统计覆盖率的文件

verbose: false
instrumentation:
    root: .
    extensions:
        - .js
    default-excludes: true
    excludes:['**/common/**','**/app/constants/**','**/lib/**']
    embed-source: false
    variable: __coverage__
    compact: true
    preserve-comments: false
    complete-copy: false
    save-baseline: false
    baseline-file: ./coverage/coverage-baseline.json
    include-all-sources: false
    include-pid: false
    es-modules: false
reporting:
    print: summary
    reports:
        - lcov
    dir: ./coverage
    watermarks:
        statements: [50, 80]
        lines: [50, 80]
        functions: [50, 80]
        branches: [50, 80]
    report-config:
        clover: {file: clover.xml}
        cobertura: {file: cobertura-coverage.xml}
        json: {file: coverage-final.json}
        json-summary: {file: coverage-summary.json}
        lcovonly: {file: lcov.info}
        teamcity: {file: null, blockName: Code Coverage Summary}
        text: {file: null, maxCols: 0}
        text-lcov: {file: lcov.info}
        text-summary: {file: null}
hooks:
    hook-run-in-context: false
    post-require-hook: null
    handle-sigint: false
check:
    global:
        statements: 0
        lines: 0
        branches: 0
        functions: 0
        excludes: []
    each:
        statements: 0
        lines: 0
        branches: 0
        functions: 0
        excludes: []
复制代码

3、单元测试

单元测试在测试分层中处于金字塔最底层的位置,单元测试作的比较到位的状况下,能过滤掉大部分的问题,而且提前发现 bug,也能够下降 bug 成本。推行一段时间的单测后发现,在有赞的 Node 框架中,业务层的 server 端只作接口组装,client 端面向浏览器,都不太适合作单元测试,因此咱们只针对基础框架和通用组件进行单测,保障基础服务能够经过单测排除大部分的问题。好比基础框架中店铺通用信息服务,单测检查店铺信息获取;好比页面级商品组件,单测检查商品组件渲染的 html 是否和原来一致。

单测方案试行了两个框架:

  • Jest[5]
  • ava[6]

比较推荐的是 Jest 方案,它支持 Matchers 方式断言;支持 Snapshot Testing,可测试组件类代码渲染的 html 是否正确;支持多种 mock,包括 mock 方法实现、mock 定时器、mock 依赖的 module 等;支持 istanbule,能够方便的获取覆盖率。

总之,前端的单测方案也愈来愈成熟,须要前端开发人员更加关注 js 单测,将 bug 扼杀在摇篮中。

4、基础库变动报警

上面咱们已经对基础服务和基础组件进行了单元测试,可是单测也不能彻底保证基础库的变动彻底没有问题,伴随着业务层引入新版本的基础库,bug 会进一步带入到业务层,最终影响 C 端用户的正常使用。那如何保障每次业务层引入新版本的基础库以后能作到全面的回归?如何让业务测试同窗对基础库变动更加敏感呢?针对这种状况,咱们着手作了一个基础库版本变动的小工具。实现思路以下:

1. 对比一次 master 代码的提交或 merge 请求,判断 package.json 中是否有特定基础库版本变动
2. 将对应基础库的先后两个版本的代码对比发送到测试负责人
3. 根据 changelog 判断这次回归的用例范围
4. 增长 gitlab webhook,只有合并到合并发布分支或者 master 分支的代码才触发检查
复制代码

这个小工具的引入能及时通知测试人员针对什么需求改动了基础组件,以及此次基础组件的升级主要影响了哪些方面,这样能避免相对黑盒的测试。

初版实现了最简功能,后续再深挖需求,能够作到前端代码变动的精准测试。

5、sentry报警

在刚接触前端测试的时候,js 的报错没有任何追踪,对于排查问题和定位问题有很大困扰。所以咱们着手引入了 sentry 报警监控,用于监控线上环境 js 的运行状况。

sentry[7] 是一款开源的错误追踪工具,它能够帮助开发者实时监控和修复崩溃。

开始咱们接入的方式比较简单粗暴,直接全局接入,带来的问题是报警信息很是庞大,全局上报后 info、warn 信息都会打出来。

更改后,使用 sentry 的姿式是:

  • sentry 的全局信息上报,并进行筛选
    • 错误类型: TypeError 或者 ReferenceError
    • 错误出现用户 > 1k
    • 错误出如今 js 文件中
    • 出现错误的店铺 > 2家
  • 增长核心业务异常流程的主动上报

最终将筛选后的错误信息经过邮件的形式发送给告警接收人,在固定的时间集中修复。

6、业务报警

除了 sentry 监控报警,Node 接口层的业务报警一样是必不可少的一部分,它能及时发现 Node 提供的接口中存在的业务异常。这部分是开发和运维同窗作的,包括在 Node 框架底层接入日志系统;在业务层正确的上报错误级别、错误内容、错误堆栈信息;在日志系统增长合理的告警策略,超过阈值以后短信、电话告警,以便于及时发现问题、排查问题。

业务告警是最能快速反应生产环境问题的一环,若是某次发布以后发生告警,咱们第一时间选择回滚,以保证线上的稳定性。

7、约定规范

除了上述的一些测试和告警手段以外,咱们也作了一些流程规范、用例维护等基础建设,包括:

  • 发布规范
    • 多个平常分支合并发布
    • 限制发布时间
    • 规范发布流程
    • 整理自测核心检查要点
  • 基线用例库
    • 不一样业务 P0 核心用例按期更新
    • 项目用例按期更新到业务回归用例库
    • 线上问题场景及时更新到回归用例库

目前有赞的前端测试套路基本就是这样,固然有些平时的努力没有彻底展开,例如接口测试中增长返回值结构体对比;增长线上接口或页面的拨测[8];给开发进行自测用例设计培训等等。也还有不少新功能探索中,如接入流量对比引擎,将线上流量导到预上线环境,在代码上线前进行对比测试;增长UI自动化的截图对比;探索小程序的UI自动化等等。

参考连接:

相关文章
相关标签/搜索