e2e测试Cypress 实践总结

一、背景

经过前期对e2e(端到端)测试框架的调研,最终确定选择使用Cypress

在经过2-3天的踩坑实践,终于成功将e2e测试流程集成到项目的gitlab CI中。

现对这几天遇到的问题做一次总结。

一来可以借此反思并精进,自己在整个过程中排查和解决问题的思路方法,二来也可以作为组内e2e测试项目的实践经验供其他同学参考。

二、实践过程

2.1、Cypress安装

参考Crpress的官网(www.cypress.io),执行yarn add cypressCypress进行安装。整个安装过程很顺利。

arduino 复制代码
yarn add  cypress // 安装成功后执行下面一句
yarn cypress open

执行yarn cypress open 会自动打开Cypress 程序:

在调研文档里,我曾说过,Cypress既可以做e2e测试,也可以做单元、集成测试。

这里,我们选择第一个选项: E2E Testing。

因为我们当前还没有写测试用例,点击 E2E Testing,提示需要在我们的项目中增加以下文件:(主要帮我们生成Cypress目录,以及配置文件)。

点击continue,会在我们项目中生成Cypress目录,并将这些文件加入到Cypress中。

接下来,我们按照官方文档,写了一个测试用例,用来检查,Cypress能否正常工作。

我们在Cypress的目录e2e下新建文件:App.cy.js

scss 复制代码
describe('e2e start', () => {
  it('e2e test should start', () => {
    expect(true).to.equal(true);
  });
});

我们执行yarn cypress open, 提示选择浏览器,选择第一个Chrome。

后面的操作也很简单,点击按钮,再点击对应的测试文件,可以看到,运行成功。

至此已经验证Cypress 可以正常工作。

那么问题来了,Cypress每次运行测试用例都要弹出应用程序跑吗,那么怎么集成到CI中呢。

接下来验证Cypress 另一种方式:Headless,运行测试用例。

终端执行 cypress run,结果如下:

以上,是Cypress 安装以及验证两种方式运行测试用例,貌似一切都很顺利。

2.2、Cypress CI 集成

既然本地运行成功,那么集成到CI中也就是在.gitlab-ci.yml 写个tag 而已,说干就干。

yaml 复制代码
stages:
  - node_install
  - node_build
  - unit_test
  - e2e_test
  - deploy
  
 ...

e2e_test:
  stage: e2e_test
  script:
    - node -v
    - echo "e2e test start"
    - yarn test:cy
  allow_failure: true
  artifacts:
    when: always
    
 ...

写完代码非常自信的mergemaster

结果却出乎意料:显示缺少依赖 Xvfb

一顿google:

通过搜索,知道Xvfb是一个UNIX-like操作系统的in-memory显示服务器,有三个方案,

  • 第一个是直接安装这个Xvfb,但是不建议单独安装,因为还会报其依赖错误;
  • 第二个是执行 cypress run --headless, headless browsers不使用Xvfb, 但是这个方案也可能会出现其它问题。
  • 最推荐的是第三个了,安装Cypress 官方镜像。

因此我修改了.gitlab-ci.yml , 看看能否顺利通过。

yaml 复制代码
...
e2e_test:
  stage: e2e_test
  image: cypress/browsers:node-20.9.0-chrome-118.0.5993.88-1-ff-118.0.2-edge-118.0.2088.46-1
  script:
    - node -v
    - echo "e2e test start"
    - yarn test:cy
  allow_failure: true
  artifacts:
    when: always
  ... 

很遗憾,还是报一样的错误,也就是这个镜像并没有拉取或者是拉取不成功。

在这里,触及到了我的知识盲区,因为之前没有怎么接触过docker,出现这个问题,我的排查方向还是在配置上,认为是配置不对,在google上一通搜索。

结果是,无论是官方文档,还是其他人给出的例子(比如这个github.com)都看不出来,我这配置有什么问题。

我甚至很有耐心的看完一个介绍视频www.youtube.com,这个外国友人讲得甚至都不是英文,硬着头看他演示代码。

然而依然没有成功。

在这个过程中,只能一个一个再去排查

  • 是不是cypress/browsers node版本的问题,我修改了本地node版本问题,但是CInode版本需要运维同学帮忙改,这个先暂缓,看看其它问题。
  • script 里要也尝试安装依赖包,但是前端项目的依赖都是读取package.json, 所以也并不会安装什么我们没有配置的包。
  • 再尝试直接安装Xvfb,但yarn 中没有这个包...
  • ...
  • 再问问服务端同学呢,他们也不知道...

卡住了怎么呢?

既然CI管道中执行不成功,那么我本地安装一个docker,拉取Cypress提供的镜像,跑一跑试试。

本地电脑按照docker官方文档,很快安装成功。

接下来执行docker 拉取镜像,显示是成功的,再用docker 执行本地测试文文件。

bash 复制代码
docker pull cypress/included:10.8.0
docker run -it -v $PWD:/e2e -w /e2e cypress/included:10.8.0

也成功了!

如果docker 能运行成功,那就在CI中也配置统一的镜像包吧。

yaml 复制代码
e2e_test:
  stage: e2e_test
  image: cypress/included:10.8.0
  script:
    - node -v
    - echo "e2e test start"
    - yarn test:cy
  allow_failure: true
  artifacts:
    when: always

修改代码后,再次执行pipelines,成功了!

这成功也太突然了,这时,我一直以为是新的镜像包 cypress/included:10.8.0 起的效果。

等我再次将代码合并到master,当头一棒的事情出现了!竟然其它的tags都运行失败了!

这是什么神奇问题,node还整丢了呢?

通过再一次google,大概觉得应该是执行e2e的runner和执行installrunner不是一个,切换错误?

我意识到这个问题应该去问问运维同学了,在群里咨询后,没多久,司贤告诉我已经解决了。

原因是他修改了runner

再回头发现,执行成功了的e2e 信息里都有k8s拉取镜像的打印:

而失败的e2e测试,并没有拉取镜像的打印信息:

所以,到这样,才知道,真正使得e2e运行成功的是这个16.6.1版本的gitlab-runner起了作用。

至于gitlab-runner 16.5.0 为什么不会拉取镜像,我现在还不知道。(有知道的小伙伴可以评论里告诉我,感激不尽!)

ok,到这里问题应该都圆满解决了吧?

别高兴得太早,问题是层出不穷的,看吧:

当然这个问题,很简单,cypress默认生成的配置文件是.ts结尾的,修改成.js,然后代码做一些修改即可:

到这里,pipelines终于迎来了五连勾:

三、总结

3.1 通过跑通Cypress CI 集成流程,得出一些Cypress结论:

  • 比如镜像cypress/included:10.8.0后面的Cypress 版本和本地Cypress版本不需要一模一样,只要不是太大版本差异就可以。同理 cypress/browsers:node-16.18.1-chrome-110.0.5481.96node版本也不必一模一样;
  • 官方镜像比如 cypress/browsers:node-16.18.1-chrome-110.0.5481.96,不能擅自去更改node版本,需要去官网查看对应版本,否则没有对应的镜像,当然也会失败;
  • Cypress 最新版13,启动测试时,需要启动项目,但是10版本不需要,本地和docker包括CI管道都不需要。

3.2 排查思路反思

  • docker不太了解,导致在一个错误的方向上排查了很长时间。这个后续需要扩展自己的知识面,往服务端,运维、虚拟化技术等底层方向多些学习;
  • 这次排查问题,我在node以及 Cypress版本上也停留了很长时间,原因是过去确实遇到过因为依赖版本不一致而出现的问题经历,所以这次也认为可能出现在版本上。-- 所以说,经验并非百分百可靠,有时候仅能作参考,对于不同的问题可能需要区分看待;
  • CI管道运行环境,需要进一步学习,本次排查问题时,在script中写错了几次命令,存在着病急乱投医的行为。
  • 当然最后,我觉得遇到问题都是好事,解决问题,不断扩展自己的知识边界,自己又成长一步!

3.2 下一步计划

  • 本次只是跑通了流程,后续会针对系统的各个页面和模块在去写测试用例;
  • 完善测试报告配置;
  • 计划可能将单元测试也改为Cypress ,因为Jest是模拟浏览器去运行你的测试用例,而Cypress 是在真实的浏览器里跑,当然后者更准确。
相关推荐
qq_346295271 分钟前
require/exports 或 import/export的联系和区别,各自的使用场景
javascript
flying robot4 分钟前
小结:JavaScript 模块化工具链
javascript
inksci36 分钟前
Vue 3 打开 el-dialog 时使 el-input 获取焦点
前端·javascript·vue.js
孤的心了不冷2 小时前
【Docker】CentOS 8.2 安装Docker教程
linux·运维·docker·容器·eureka·centos
绝美焦栖3 小时前
vue复杂数据类型多层嵌套的监听
前端·javascript·vue.js
头疼的程序员3 小时前
docker学习与使用(概念、镜像、容器、数据卷、dockerfile等)
学习·docker·容器
IT小郭.3 小时前
使用 Docker Desktop 安装 Neo4j 知识图谱
windows·python·sql·docker·知识图谱·database·neo4j
淡水猫.3 小时前
hbit资产收集工具Docker(笔记版)
运维·docker·容器
我是Superman丶7 小时前
【技巧】前端VUE用中文方法名调用没效果的问题
前端·javascript·vue.js
斯~内克7 小时前
Vue 3 中 watch 的使用与深入理解
前端·javascript·vue.js