Cypress在流水线中的踩坑记录与windows测试环境搭建

由于项目比较偏前端,我们的UI自动化采用了cypress
在选型好了工具以后,所有的自动化也需要集成到jenkins流水线中集成,达到持续集成的目的

原始方案

一开始跑UI自动化所使用的salve,我们选择主流方案,使用跟编译打包同样的slave。

发现问题
  • UI自动化执行的时间比较长,最短也需要执行3分钟左右。在限制了slave管道的情况下(考虑到资源消耗,我厂设置每台slave最多同时执行5个任务),UI自动化持续独占slave,导致研发同学持续提交的过程经常被中断,拖累了生产效率。
  • 在实际执行的过程中,因为经常会出现“卡case”(跑着跑着就不动了)等问题。调查log后发现是跑case的时候自动断开浏览器session,升级cypress版本也无法解决问题。猜测可能是操作系统版本和xvfb等插件版本对chrome兼容性的问题。

改进方案

占用生产的slave问题比较好解决,先尝试用jenkins label分割slave群,独占一个台slave执行UI自动化。
Cypress卡case的问题,因为怀疑是环境问题,于是首选尝试使用官方提供的docker镜像来运行测试。同时将测试场景分成多个spec,每个spec文件中只有一个describe(调研发现卡case通常发生在初始化describe,即scenario的时候)

又发现问题
  • 使用官方提供的镜像后,发现卡case的问题虽然次数不那么频繁,但是依然存在。
  • docker中运行chrome/electric市场崩溃。尝试过增加初始内存,但也只是缓解崩溃次数。
  • 中途考虑过换自动化方案,使用webdriver+selenium grid的上古方案。在docker环境下实际执行过程中还是回碰到chrome崩溃的问题。另外项目中途换工具的成本其实也不低。还有就是爽过cypress以后,实际上已经回不去webdriver了。。

终极方案

我厂大部分测试同学使用的是windows机器开发脚本。在碰到卡case啊,chrome崩溃等问题的时候,windows机器均无法复现跑得飞起。那是不是使用windows机器作为slave就可以解决上面碰到的所有问题了呢。

Windows slave的必要性
  • 借助浏览器的headless模式,目前在持续集成中我们比较主流的做法是在linux slave中直接跑UI自动化。
    但是Cypress的本质上是浏览器插件,chrome等浏览器目前支持的headless模式还无法提供对插件的支持。操作系统为Linux的jenkins slave中必须按照官方提示安装xvfb等插件来提供运行支持。
apt-get install xvfb libgtk2.0-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2
  • 从用户使用习惯上考虑,市面上绝大部分的用户使用的是windows。使用windows及真实浏览器执行出的结果是最可信的。

确定了必要性和可行性,就开始准备做windows slave。
公司的jenkins等基础设施建在云主机上。需要增加slave的时候,必须要走财务流程申请新的云主机,流程冗长复杂,而且还不便宜。
然后我突然想到办公室里面有好几台空闲的的PC机器(win10),用作显示CI monitor,略显浪费。那是不是可以把这几台windows pc做成jenkins slave集群,当土生云使用呢。

给jenkins增加windows slave
通信问题

为了达到把本地机器装载到jenkins slave集群中的目的,host和slave之间的通信问题得先解决。
找运维同学配合,绕过各种IP、访问限制,确保两点即可

  • host和slave之间可以相互访问
  • 开发机和slave之间可以相互访问
在slave上安装依赖环境

需要在slave上安装执行jenkins以及UI自动化的环境

  • java8
  • nodejs
  • git
    等等
在slave上安装jenkins agent

按照这个教程,做到第四步。后面,我们采用直接在slave上用bat文件启动agent.jar的方案。

启动脚本

其中-Dfile.encoding=UTF8可以解决在console中的乱码问题
然后依次把其他slave机器设置好,执行bat文件后,java进程以cmd窗口的形式存在在slave上。
成功后,jenkins上查看结果。
windows slaves

做到这一步,只需要把UI测试配置上这个slave集群的label,然后就可以正常在流水线中跑UI自动化了。

新的问题

按理来说现在自动化也可以独立跑了,cypress也不挂了,完美了啊。
结果在实践中发现承载jenkins的命令行窗口,经常因为不同的原因挂掉

  • 其他同学看到命令行习惯性的关掉
  • win10的自动更新机制(关了自动更新服务也不起作用)会定时重启机器
  • 在命令行窗口中点击了右键让命令行窗口处于挂起状态

所以又得想个办法把这些窗口隐藏起来。

使bat变成windows服务

两种方式可以达到目的

  • 使用nssm.exe工具,借助工具的托管,可以轻松的让bat变成windows services
nssm.exe install [服务名] [bat文件路径]
  • 根据教程第四步及以后的内容做成服务。(不推荐,使用此方法做成服务后,删除服务时候需要使用sc命令。比较麻烦)

做成windows服务以后,再也不同担心被误关窗口了。而且重启后也会自动启动。

问题又来了

jenkins agent做成服务以后,跑UI自动化的时候,发现cypress的viewport设置失效,始终会以手机的viewport来执行测试。
经过调查和多次验证,发现问题还真出在jenkins agent被.net框架包装成服务时。同样的bat文件,直接执行就不会有viewport的问题。

所以必须要放弃服务化,用另外一种方式使agent以命令行方式执行。

vbs

虽然start \min命令,可以使bat文件在一开始就以最小化的方式执行。这种方式下我们还是能在任务栏看到这个命令行窗口。

所以最终还是直接选择使用vbs来包装这个bat文件。

  • 在bat文件同目录中创建记事本文件
  • 键入下面脚本,其中Run命令后面跟的是用cmd来跑jenkins agent启动bat的意思。参数0表示启动后不在界面显示(只能通过任务管理器查看进程)。完了以后把扩展名改成vbs。
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run("cmd.exe /c jenkins_slave_start.bat"), 0
  • 右键创建这个脚本的快捷方式,在windows->run中输入shell:startup打开启动项,把快捷方式拖入到启动文件夹中。


    原始目录中的vbs文件和启动目录中的快捷方式

双击启动这个进程后,windows slave成功上线。服务器的界面上也看不到任何窗口了。而且服务器重启的时候,也会通过启动项把这个服务启动起来。

同样的方式,我们也用来启动了selenium grid等其他可以用bat启动的服务。

不完美的地方

至此,windows slave算搭建完成了。vbs隐藏界面的方式看上去很美好,但是也会有问题, 比如

  • 操作反馈十分不友好,你甚至不知道自己有没有点击成功。需要去查看进程。
  • 无法看到log。如果服务出了问题没办法拿到日志。

所以后面还可以改进的地方还挺多。
顺带提一下因为重新引入windows slave的关系,最近又重新捡起了vbs,开心 -v-

你可能感兴趣的:(Cypress在流水线中的踩坑记录与windows测试环境搭建)