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 是在真实的浏览器里跑,当然后者更准确。
相关推荐
web行路人8 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0019 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼92127 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂30 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二1 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y5236481 小时前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
fruge2 小时前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js
嚣张农民2 小时前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试