文 | 周清华 on 测试

前言

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

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

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

对于每个不同的层,我们都做了一些事情来保障质量,包括:

  • 针对整个业务层的 UI 自动化、核心接口|页面拨测;

  • 针对 client 层的 sentry 报警;

  • 针对 server 层的接口测试、业务报警;

  • 针对基础框架和通用组件的单元测试;

  • 针对通用组件变更的版本变更报警;

  • 针对线上发布的流程规范、用例维护等。

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

一、UI 自动化

很多人会认为,UI 自动化维护成本高、性价比低,但是为什么在有赞的前端质量保证体系中放在了最前面呢?

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

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

1.1 框架选择

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

UI 自动化框架有很多种,包括 selenium、phantom;对比后发现 puppeteer 比较轻量,只需要增加一个 npm 包即可使用;它是基于事件驱动的方式,比 selenium 的等待轮询更稳当、性能更佳;另外,它是 chrome 原生支持,能提供所有 chrome 支持的 api,同时我们的业务场景只需要覆盖 chrome,所以它是最好的选择。

-- mocha[2] + mochawesome[3],mocha 是比较主流的测试框架,支持 beforeEach、before、afterEach、after 等钩子函数,assert 断言,测试套件,用例编排等。

js 测试框架同样有很多可以选择,mocha、ava、Jtest 等等,选择 mocha 是因为它更灵活,很多配置可以结合第三方库,比如 report 就是结合了 mochawesome 来生成好看的 html 报告;断言可以用 powser-assert 替代。

1.2 脚本编写

  • 封装基础库

    • 封装 pc 端、h5 端浏览器的初始化过程

    • 封装 pc 端、h5 端登录统一处理

    • 封装页面模型和组件模型

    • 封装上传组件、日期组件、select 组件等的统一操作方法

    • 封装 input、click、hover、tap、scrollTo、hover、isElementShow、isElementExist、getElementVariable 等方法

    • 提供根据 “html 标签>>页面文字” 形式获取页面元素及操作方法的统一支持

    • 封装 baseTest,增加用例开始、结束后的统一操作

    • 封装 assert,增加断言日志记录

  • 业务用例

    • 安装基础库

    • 编排业务用例

1.3 执行逻辑

  • 分环境执行

    • 增加预上线环境代码变更触发、线上环境自动执行

  • 监控源码变更

    • 增加 gitlab webhook,监控开发源码合并 master 时自动在预上线环境执行

    • 增加 gitlab webhook,监控测试用例变更时自动在生产环境执行

  • 每日定时执行

    • 增加 crontab,每日定时执行线上环境

二、接口测试

接口测试主要针对于 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: []

三、单元测试

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

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

  • Jest[5]

  • ava[6]

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

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

四、基础库变更报警

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

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

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

第一版实现了最简功能,后续再深挖需求,可以做到前端代码变更的精准测试。

五、sentry 报警

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

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

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

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

  • sentry 的全局信息上报,并进行筛选

    • 错误类型: TypeError 或者 ReferenceError

    • 错误出现用户 > 1k

    • 错误出现在 js 文件中

    • 出现错误的店铺 > 2家

  • 增加核心业务异常流程的主动上报

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

六、业务报警

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

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

七、约定规范

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

  • 发布规范

    • 多个日常分支合并发布

    • 限制发布时间

    • 规范发布流程

    • 整理自测核心检查要点

  • 基线用例库

    • 不同业务 P0 核心用例定期更新

    • 项目用例定期更新到业务回归用例库

    • 线上问题场景及时更新到回归用例库

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

参考链接:

  • [1] https://github.com/GoogleChrome/puppeteer

  • [2] https://www.npmjs.com/package/mocha

  • [3] https://www.npmjs.com/package/mochawesome

  • [4] https://github.com/gotwarlost/istanbul

  • [5] https://github.com/facebook/jest

  • [6] https://github.com/avajs/ava

  • [7] https://docs.sentry.io

  • [8] https://tech.youzan.com/youzan-online-active-testing/

-The End-

Vol.174

有赞技术团队

为 442 万商家,150 个行业,330 亿电商交易额

提供技术支持

微商城|零售|美业 | 教育

微信公众号:有赞coder    微博:@有赞技术

技术博客:tech.youzan.com

The bigger the dream,

the more important the team.

有赞前端质量保障体系相关推荐

  1. 浅谈有赞搜索质量保障体系

    作者:张家瑜 部门:业务中台/测试开发 前言 有赞搜索中台的前身是ES中间件,并没有一个中台的概念,相应的就会有一个问题,业务接入搜索场景的时候还需要为此投入开发资源同步搜索设计,一个需求上线往往耗时 ...

  2. 研发质量保障体系搭建

    质量保障体系的搭建,并非测试人员一方的责任,需要产品.研发.项目经理.运维工程师一起参与来搭建这个体系. 一.研发流程阶段 1. 需求阶段 需求阶段主要确保「产品经理」输出的原始需求能被项目经理.研发 ...

  3. SLA 4 个 9 ,贝壳高可用架构的质量保障体系

    导语 | 贝壳用户需求和用户量的不断增长,对系统的高可用性提出了更高的要求,服务端的质量保证工作该如何开展?本文是对贝壳找房-基础平台中心-质量平台赋能部总监--项旭老师在云+社区沙龙online的分 ...

  4. 测试用例优先级划分_全面的质量保障体系之测试用例分级

    在<全面的质量保障体系之发现缺陷>中提到测试用例分级的应用,以最少的测试用例实现覆盖更多的测试场景,以提高测试的精准度.测试用例分级是每个公司都在做的事情,但如何精细化的做好测试用例分级, ...

  5. 全球化安全生产 质量保障体系建设探索

    作者:肖刚毅.张俊.李晶磊(全球化业务平台团队) 全球化电商中的业务.技术及架构和国内技术都有一定差异,从安全生产保障和质量保障角度,这些差异带来了更多的挑战,本文将为大家分享安全生产和质量保障相关的 ...

  6. ToB质量保障体系建设思考

    互联网企业向ToB转型要实现"高质量.低成本.高效率"交付的目标,需要构建一套完整的质量保障体系.通过总结行业质量保障的最佳实践,结合对ToB业务和互联网的业务的理解,个人认为质量 ...

  7. 浅谈业务质量保障体系的建设

    文章目录 前言 质量保障的内容 效率工程 工程规范 内建质量 质量保障实践 质量保障第初级阶段 质量保障第二阶段 迭代流程管理 需求管理 用例管理 缺陷管理 文档管理 线上问题统一管理 统一的问题上报 ...

  8. 质量保障体系建设演进案例

    在业务早期发展阶段,主要是产品驱动.研发和测试互相配合.不同的测试方法是验证和保障交付质量的手段,而不是构建质量体系的基石.测试的努力带来的更多是一些"安全感",而非安全保障.因此 ...

  9. 得物交易域数据仓库数据质量保障体系建设 |大数据测试

    一.背景介绍 目前得物数仓测试,划分成交易.增长.社区等多个模块,不同的数仓测试域,都会有一名测试人员负责跟进,根据每个版本每个域资源实际投入情况,组内会适当的调整资源,以满足日常迭代需要:单交易域这 ...

最新文章

  1. 【运维】阿里云宝塔面板部署JavaWeb项目
  2. pr如何处理音效_学视频剪辑 PR通关教学课程 教程
  3. gis python 桌面,arc-utils-用于Esri ArcGIS桌面软件的Python实用程序-Grant Herbert
  4. 程序设计竞赛资源索引
  5. 10-angular.identity
  6. UML类图(Class Diagram)中类与类之间的关系及表示方式
  7. 清风数学建模学习笔记——模糊综合评价法原理及案例分析讲解
  8. EF(EntityFramework) 的 CodeFirst 使用指南二(基本使用)
  9. 计算机组成原理简答课后答案,计算机组成原理_习题集(含答案).doc
  10. 模数转换(A/D)与数模转换(D/A)
  11. 计算机主机忘了密码怎么办,如果我忘记了笔记本计算机的开机密码怎么办
  12. coc机器人苹果_coc机器人
  13. 软件中级设计师 - 计算机网络
  14. java取字符串首字母_java 获取中文字符的首字母
  15. 亲身经历告诉你,学好英语的正确姿势(文末附自建英语学习网站)
  16. 【文件包含漏洞03】文件包含漏洞的空字符绕过及六种利用方式
  17. 微信小程序对接大华摄像头
  18. mysql根据中文拼音分组_【改进篇】使用MySql实现好友昵称按拼音排序或分组
  19. 955.WLB 不加班公司名单(持续更新)
  20. 软件工程毕业设计题目安卓Android移动端推荐

热门文章

  1. 华为OD机试 - 欢乐的周末(Java JS Python)
  2. 加油站都需要什么手续_油圈网:开加油站,需要在哪些地方审批些什么手续呢?...
  3. 煽情的儿子543=随笔
  4. python爬虫详解(四)——使用爬虫爬取你想要的图片 类似于图片下载器【百度引擎】
  5. StyleGAN v1 :用于生成高质量图像数据的生成对抗方法
  6. 设置linux引导windows,linux与windows双引导设置【原创】
  7. 利用text-shadow叠加取值制作火焰文字
  8. 反对996为何是一场闹剧
  9. 软件杯龙源风电赛题培训!千万分钟数据和全流程基线等你来战
  10. deeplearning笔记5:序列模型