从零搭建e2e测试系统
本文如何食用:本文只是介绍一下搭建e2e测试系统的思路,为将来搭建e2e系统的朋友提供一种思路。
本文写作想法:好久没写文章了,把最近的工作做个简单的记录
需求背景
公司的收银台系统接入大量第三方支付渠道,为保障产品和渠道质量,需要对项目进行e2e测试。
目录
- 编写代码
- e2e核心代码
- 渠道用例的配置文件编写
- 自动化生成测试用例(根据渠道用例的配置文件生成测试用例)
- 测试结果持久化
- MongoDB持久化
- 可视化部分
- 服务端代码
- 客户端代码
- e2e核心代码
- 部署配置上线
- docker生成
- nginx配置
编写代码
e2e 核心代码
-
对比
Selenium
e2e测试框架,选择Playwright
,是微软官方所出。
Playwright
相比于Selenium
提供更丰富的API,无需额外的web-driver支持,更适合快速开发。 -
如何设计动态的测试用例
由于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) }) }) 复制代码
-
测试用例需要哪些配置
首先需要考虑到需要页面的基本信息,如”url”、”title”。再考虑到测试的每一步,如”操作事件”、”事件名称”、”输入填充值”。 页面还需要有登录态(通过设置cookie实现) -
测试用例怎么编写
一个最基本的测试用例应该是以下格式,需要test(title, async ({browser}, testInfo) => { // 1. 设置页面基本信息 // 2. 设置测试报告的额外信息 // 3. 设置页面的额外信息,如cookie // 4. 打开测试的页面 // 5. 循环执行测试的步骤 // 5.1 将测试每一步的额外信息添加到测试报告 // 5.2 定位需要测试的html标签或页面,返回定位器(locator) // 5.3 根据定位器,执行此定位器的内容 }) 复制代码
下面是一种自动生成用例方案供参考:
-
怎么利用
Playwright
的定位器”locator”定位到hml标签或页面- 定位html标签需要考虑到定位方式,如标签属性查找、id查找、xpath查找,使用页面定位器:
page.locator
。 - iframe内的元素需要使用frame定位器:
page.frameLocator.locator
。 - 而页面跳转、打开新页面,需要使用不同的页面监听器,如
page.on
、context.on
。监听到页面事件之后,将定位器定位到新页面的根元素即可。
- 定位html标签需要考虑到定位方式,如标签属性查找、id查找、xpath查找,使用页面定位器:
-
如何操作html标签
拿到定位器”locator”之后,根据不同的操作,如点击事件,滑动事件,输入事件。决定不同的操作即可,如点击操作locator.click()
测试结果持久化
- 选用
mongodb
作为持久化的数据库,设计两个集合TEST_COLLECTION、TEST_ITEM_COLLECTION
,第一个集合放置每次测试(每次测试包含多个渠道)的结果,第二个集合放置渠道的结果。 - 两个集合具有关联关系,如果借用关系数据库是说法就是 “渠道的结果的外键是每次测试结果的主键”。
- 体现在数据库操作上就是:存储的时候先存储每次测试结果 ,拿到_id之后再作为外键存储渠道的结果,可以取名
testId
; 查询时候,可以提供3个接口,分别是:查询每次测试的结果、查询不同渠道的结果、查询测试+渠道的完整结果。 - 在持久化的同时,可以上报一份当前测试结果到企业微信,可以包含测试时长、失败的渠道、成功的渠道、失败描述等信息,效果可以如下:
- 如何自动触发测试呢?提供一个接口,当访问接口时,触发测试。
可视化
- 展示测试结果最基本需要2个页面:按每次测试页、按渠道页,均支持搜索,分页查询,所使用的技术为
Next.js
。
编写页面的部分就不过多介绍了,以下是两个页面的效果。
- 便于查看具体的错误页面,利用
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.sh
和 auto_set_cpus.sh
主要文件做了以下事情:
- 设置nginx 的 worker_processes、worker_processes_num、worker_cpu_affinity
- 执行/sbin/nginx -g ‘daemon off;’
- 根据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: 根据编写的基础创建镜像:
- 初始化脚本:复制编写好的
nginx.conf
到/etc/nginx/conf.d
。此目录为nginx的默认执行的目录,使用nginx -t
可以查看具体配置。 - DockerFile:安装npm依赖和pm2
- 实例的启动命令:
pm2 start npm -- run prod:client && /bin/bash /data/scripts/run.sh
。prod: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配置