从零搭建e2e测试系统

从零搭建e2e测试系统

本文如何食用:本文只是介绍一下搭建e2e测试系统的思路,为将来搭建e2e系统的朋友提供一种思路。
本文写作想法:好久没写文章了,把最近的工作做个简单的记录

需求背景

公司的收银台系统接入大量第三方支付渠道,为保障产品和渠道质量,需要对项目进行e2e测试。

目录

  • 编写代码
    • e2e核心代码
      • 渠道用例的配置文件编写
      • 自动化生成测试用例(根据渠道用例的配置文件生成测试用例)
    • 测试结果持久化
      • MongoDB持久化
    • 可视化部分
      • 服务端代码
      • 客户端代码
  • 部署配置上线
    • docker生成
    • nginx配置

编写代码

e2e 核心代码

  1. 对比Selenium
    e2e测试框架,选择Playwright,是微软官方所出。
    Playwright相比于Selenium提供更丰富的API,无需额外的web-driver支持,更适合快速开发。

  2. 如何设计动态的测试用例
    由于Playwright不支持动态生成测试用例,即test语句必须要放到测试文件的顶层,而不能放在循环语句内创建测试用例。
    所以,必须考虑一种动态生成测试用例的方法。继而就想到了使用模板文件结合node的fs模块来动态生成测试用例:

    /* 文件生成器 */
    const files = fs.readdirSync(path.resolve(__dirname,'./channels')) // 得到所有渠道的配置文件
    const base = (fileName: string) => `这里是测试模板代码${fileName}` // 测试用例的模板代码
    files.forEach((file: string) => { // 遍历所有的渠道配置文件,生产测试用例
      fs.writeFile(path.resolve(__dirname, `./tests/${file}`.replace('.ts', '.spec.ts')), base(file), (e: any) => {
        e && console.error(e)
      })
    })
    复制代码
  3. 测试用例需要哪些配置
    首先需要考虑到需要页面的基本信息,如”url”、”title”。再考虑到测试的每一步,如”操作事件”、”事件名称”、”输入填充值”。 页面还需要有登录态(通过设置cookie实现)

  4. 测试用例怎么编写
    一个最基本的测试用例应该是以下格式,需要

    test(title, async ({browser}, testInfo) => {
        // 1. 设置页面基本信息
        // 2. 设置测试报告的额外信息
        // 3. 设置页面的额外信息,如cookie
        // 4. 打开测试的页面
        // 5. 循环执行测试的步骤
        //    5.1 将测试每一步的额外信息添加到测试报告 
        //    5.2 定位需要测试的html标签或页面,返回定位器(locator) 
        //    5.3 根据定位器,执行此定位器的内容
    })
    复制代码

    下面是一种自动生成用例方案供参考:

generate.png

  1. 怎么利用Playwright的定位器”locator”定位到hml标签或页面

    1. 定位html标签需要考虑到定位方式,如标签属性查找、id查找、xpath查找,使用页面定位器:page.locator
    2. iframe内的元素需要使用frame定位器:page.frameLocator.locator
    3. 而页面跳转、打开新页面,需要使用不同的页面监听器,如page.oncontext.on。监听到页面事件之后,将定位器定位到新页面的根元素即可。
  2. 如何操作html标签
    拿到定位器”locator”之后,根据不同的操作,如点击事件,滑动事件,输入事件。决定不同的操作即可,如点击操作locator.click()

测试结果持久化

  • 选用mongodb作为持久化的数据库,设计两个集合TEST_COLLECTION、TEST_ITEM_COLLECTION,第一个集合放置每次测试(每次测试包含多个渠道)的结果,第二个集合放置渠道的结果。
  • 两个集合具有关联关系,如果借用关系数据库是说法就是 “渠道的结果的外键是每次测试结果的主键”。
  • 体现在数据库操作上就是:存储的时候先存储每次测试结果 ,拿到_id之后再作为外键存储渠道的结果,可以取名testId; 查询时候,可以提供3个接口,分别是:查询每次测试的结果、查询不同渠道的结果、查询测试+渠道的完整结果。
  • 在持久化的同时,可以上报一份当前测试结果到企业微信,可以包含测试时长、失败的渠道、成功的渠道、失败描述等信息,效果可以如下:

wx.png

  • 如何自动触发测试呢?提供一个接口,当访问接口时,触发测试。

可视化

  • 展示测试结果最基本需要2个页面:按每次测试页、按渠道页,均支持搜索,分页查询,所使用的技术为Next.js

编写页面的部分就不过多介绍了,以下是两个页面的效果。

testPage.png

testPage2.png

  • 便于查看具体的错误页面,利用PlayWright生成截图或 跟踪查看器 ,然后提供一个接口供访问。

部署配置上线

注意:不同的公司,不同的环境,具体会有所差异。因为利用了公司的服务治理能力,这里只介绍需要手动维护的部分。

docker基础镜像编写:

Playwright提供了一个基础镜像mcr.microsoft.com,利用此镜像为基础镜像,再安装nginx。下面是一个编写好的dockerfile。

FROM mcr.microsoft.com/playwright:focal
RUN apt-get update -y && \
    apt-get install nginx -y && npm -v && node -v &&  npm i playwright -g
COPY /root/run.sh  /data/scripts/run.sh
COPY /root/auto_set_cpus.sh  /data/scripts/auto_set_cpus.sh
复制代码

其中 run.shauto_set_cpus.sh主要文件做了以下事情:

  1. 设置nginx 的 worker_processes、worker_processes_num、worker_cpu_affinity
  2. 执行/sbin/nginx -g ‘daemon off;’
  3. 根据nginx实际安装目录,设置/sbin/nginx权限、设置/etc/nginx的同步链接等。

nginx配置:

  • step1: 由于项目的后端koa服务和前端nextjs可视化项目在同一份代码里,且启动了3000和3001两个端口,所以需要监听两个端口。

nginx.conf 做如下配置:

server{
  listen 81;
  server_name aa.bb.com;
  location / {
      proxy_set_header Host $host;
      proxy_pass http://127.0.0.1:3001;
  }
}
server{
  listen 80;
  server_name aa.bb.com;
  location / {
      proxy_set_header Host $host;
      proxy_pass http://127.0.0.1:3000;
  }
}
复制代码
  • step2: 根据编写的基础创建镜像:

    1. 初始化脚本:复制编写好的nginx.conf/etc/nginx/conf.d。此目录为nginx的默认执行的目录,使用nginx -t可以查看具体配置。
    2. DockerFile:安装npm依赖和pm2
    3. 实例的启动命令:pm2 start npm -- run prod:client && /bin/bash /data/scripts/run.shprod:client是我们项目的启动命令,
      会启动后端koa服务和前端nextjs可视化服务。而/data/scripts/run.sh就是docker基础镜像里所添加的脚本。
  • step3:云服务设置
    在云服务里做Locations配置,同一份实例,分别映射到80和81端口。其余配置走默认即可。

  • step4: 进行CI/CD

这里就不展开了,本项目是利用的公司的服务治理能力。使用的是gitlab-ci。
但是其中gitlab-ci部分,直接就 echo "the script"了,而在CD部分才进行的打包运行(因为涉及到自动化生成测试用例,在CI部分打包还是一样麻烦),
这里是Playwright推荐的ci配置

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享