Node.js躬行记(28)——Cypress自动化测试实践
最近在研究如何提升项目质量,提炼了许多个用于自测的测试用例,但是每次修改后,都手工测试,成本太高,于是就想到了自动化测试。
在一年前已将 Cypress 集成到管理后台的项目中,不过没有投入到实践中。今天在实践时发现,版本已经到了 12.X,当时集成的版本是 8.X。
一、准备
在重新安装后,将之前的目录直接删除,运行命令后。
npx cypress open
1)目录
又会在根目录自动生成新文件,测试用例都会写在 e2e 目录中。
|-- downloads
|-- e2e
|----- example.spec.js
|-- fixtures
|-- support
将 cypress open 命令添加到 scripts 中,就能通过 npm run cypress 命令执行E2E测试了。
{
"scripts": {
"cypress": "cypress open"
}
}
2)启动
在刚启动时,会先让你选择一款浏览器,我选择了 Chrome。

然后就会自动打开浏览器,右边的控制台我自己打开的,用于查看通信和打印信息。

中间有许多自动生成的 demo spec,初学者可以作为参考。
在点击某一个 spec 文件后,就会进入测试页面,左侧是可以回溯的测试过程和结果,中间是在执行的界面。
若测试不通过,会有醒目的红色错误提示。

二、实践
本次实践的测试对象是一个管理后台,管理后台是需要登录的,肯定不能在每一个测试用例都要重复登录的操作。
况且,我们的后台会限制登录次数,若登录太多,就会禁用账号。
1)登录
思前想后,决定直接存储登录后的鉴权信息,我们在登录后,会将此信息存储到 localStorage 中。
此时需要考虑一个问题,那就我团队中每个人的登录账号是不同的,如何存储这些信息。
阅读官方文档后,发现可以将配置信息放在 fixtures 目录中,创建 config.json 文件,内容如下。
{
"name": "xxx@xxx.me",
"pwd": "yyy2023",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
"authorities": "*"
}
config.json 文件会被版本忽略,所以文件即使被修改,也不会提交到版本库中。
然后将存储的功能封装成一条命令,这样在各个测试用例中调用会比较简洁。
Cypress.Commands.add('saveToken', () => {
cy.fixture('config.json').then((config) => {
const { token, authorities } = config;
localStorage.setItem('token', token);
localStorage.setItem('authorities', authorities);
});
});
在 beforeEach() 方法中只需执行 cy.saveToken() 就能保持登录态。
describe('短链服务', () => {
beforeEach(() => {
cy.saveToken(); // 保持登录态
cy.visit('/operate/shortChain');// 跳转页面
});
});
2)测试
在解决登录态后,就开始正式的测试。
Cypress 的断言集成了 Chai,并且扩展了 Sinon 和 jQuery,也就是说,可以在框架内使用它们提供的功能。
下图是需要测试的短链服务界面,接下来会测试新建、更新、查询、分页和删除。

点击新建,会有一个弹框,在弹框中有一个表单。

cy.get() 用于查找元素,其参数可以是一个 CSS 选择器字符串,官方文档有专门一栏介绍查询方法。
cy.type() 用于填写文本框,官方还提供了点击、双击、上传文件等功能。scrollBehavior: false 是为了禁止移动滚动条。
页面截图需要上传,测试用的图像保存在 fixtures 目录中,cy.fixture() 可以读取此目录中的文件。
cy.selectFile() 用于上传文件,demo 加了个 @ 符号,不加就无法获取到文件。
it('存储', () => {
// 定位到新建按钮
cy.get('.ant-btn').first().click();
cy.wait(500);
// 在填写表单控件时禁用滚动
cy.get('.ant-modal #url').type(`http://www.xxx.com/test${random()}.html`,
{ scrollBehavior: false });
cy.get('.ant-modal #remark').type('测试', { scrollBehavior: false });
// 上传图像,图像存储在 fixtures 目录内
cy.fixture('demo.png', { encoding: null }).as('demo');
cy.get('input[type=file]').selectFile('@demo', { force: true });
cy.wait(1000);
// 存储
cy.get('.ant-modal .ant-btn-primary').click();
cy.get('.ant-modal').should('not.exist'); // 断言存储流程是否正常
cy.scrollTo(0, 0);
cy.wait(2000);
});
cy.wait() 就是等待,因为自动操作速度很快,有时候需要停顿下,用肉眼观察下结果。
cy.should() 用于创建断言,这与之前的 expect() 断言稍有不同,其参数就是断言结果,关键字可以参考 Chai 的断言方法。
Cypress 提供了众多的 API,还有很大的挖掘空间,并且提供了丰富的 demo,学习起来也比较方便。
Node.js躬行记(28)——Cypress自动化测试实践的更多相关文章
- Node.js躬行记(25)——Web自动化测试
网页在提测流转给 QA 后,如何能帮他们更有效而准确的完成测试,是我一直在思考的一个问题. QA 他们会对网页编写测试用例,在提测之前会让我们将优先级最高的用例跑通,这在一定程度上能够避免频繁的返工, ...
- Node.js躬行记(26)——接口拦截和页面回放实验
最近在研究 Web自动化测试,之前做了些实践,但效果并不理想. 对于 QA 来说,公司的网页交互并不多,用手点点也能满足.对于前端来说,如果要做成自动化,就得维护一堆的脚本. 当然,这些脚本也可以 Q ...
- Node.js躬行记(1)——Buffer、流和EventEmitter
一.Buffer Buffer是一种Node的内置类型,不需要通过require()函数额外引入.它能读取和写入二进制数据,常用于解析网络数据流.文件等. 1)创建 通过new关键字初始化Buffer ...
- Node.js躬行记(2)——文件系统和网络
一.文件系统 fs模块可与文件系统进行交互,封装了常规的POSIX函数.POSIX(Portable Operating System Interface,可移植操作系统接口)是UNIX系统的一个设计 ...
- Node.js躬行记(4)——自建前端监控系统
这套前端监控系统用到的技术栈是:React+MongoDB+Node.js+Koa2.将性能和错误量化.因为自己平时喜欢吃菠萝,所以就取名叫菠萝系统.其实在很早以前就有这个想法,当时已经实现了前端的参 ...
- Node.js躬行记(6)——自制短链系统
短链顾名思义是一种很短的地址,应用广泛,例如页面中有一张二维码图片,包含的是一个原始地址(如下所示),如果二维码中的链接需要修改,那么就得发代码替换掉. 原始地址:https://github.com ...
- Node.js躬行记(15)——活动规则引擎
在日常的业务开发中,会包含许多的业务规则,一般就是用if-else硬编码的方式实现,这样就会增加逻辑的维护成本,若无注释,可能都无法理解规则意图. 因为一旦规则有所改变,那么就需要修改代码再发布代码, ...
- Node.js躬行记(19)——KOA源码分析(上)
本次分析的KOA版本是2.13.1,它非常轻量,诸如路由.模板等功能默认都不提供,需要自己引入相关的中间件. 源码的目录结构比较简单,主要分为3部分,__tests__,lib和docs,从名称中就可 ...
- Node.js躬行记(21)——花10分钟入门Node.js
Node.js 不是一门语言,而是一个基于 V8 引擎的运行时环境,下图是一张架构图. 由图可知,Node.js 底层除了 JavaScript 代码之外,还有大量的 C/C++ 代码. 常说 Nod ...
- Node.js躬行记(23)——Worker threads
Node.js 官方提供了 Cluster 和 Child process 创建子进程,通过 Worker threads 模块创建子线程.但前者无法共享内存,通信必须使用 JSON 格式,有一定的局 ...
随机推荐
- 解决Vue打包后背景图片路径错误问题(转)
1.原因解析 当用vue-cli自动构建项目后,有两种运行方法,分别是: npm run dev : 提供一个开发的环境,自动热更新,资源使用绝对路径,所以可以正常看到背景图片. npm run bu ...
- UniDBGrid控件的几个功能优化
内容自动换行 默认UniDBGrid的cell内的内容如果超出表格列宽并不自动换行和调整行高,给客户带来极大的不方便,通过修改ServerModule的属性CustomCSS可以实现. <sty ...
- 关于 manacher 的一个小细节
在该算法中,我们需要用到一个数组 hw[i] ,代表 i 的最大回文半径.而且这个半径不包括 i 本身(若串为 ccc 则 hw 为 1). 这时最终答案为最大的 hw 减一. 为什么要减一呢?最终的 ...
- Vue2模版编译(AST、Optimize 、Render)
在Vue $mount过程中,我们需要把模版编译成render函数,整体实现可以分为三部分: parse:解析模版 template生成 AST语法树 optimize: 优化 AST语法树,标记静态 ...
- java 实现文件夹上传(springBoot 框架)
有时我们后台管理等服务可能会有这样一个简单需求,就是根据文件夹将整个文件夹下的所有资源都上传到我们的服务器上,本人也是搜索了大量资料,最终以最简单便捷的方式实现该功能,具体操作步骤如下 一.前端如何设 ...
- 你需要知道的Symbols
著名symbol 著名symbol是一个在不同领域中都相同且未注册的symbol.如果我们要列出著名symbol,它们会是: Symbol.iterator Symbol.toStringTag Sy ...
- DBA面试小结
问题描述:一个DBA在面试过程中,面试官最喜欢提问哪些问题,经过这些天的面试经历,总结了一些面试经验. 普通的外包可能只有一轮技术面试再加一轮人资面试,外包项目一般急需用人,所以面试流程基本简化,合适 ...
- tar:Error is not recoverable:exiting now
问题描述:文件包在不同网络跟介质之间传输,导致文件破损,如何使用md5的方式去对比文件的完整性 tar:Child returned status 1 tar:Error is not recover ...
- Go For Web:一篇文章带你用 Go 搭建一个最简单的 Web 服务、了解 Golang 运行 web 的原理
前言: 本文作为解决如何通过 Golang 来编写 Web 应用这个问题的前瞻,对 Golang 中的 Web 基础部分进行一个简单的介绍.目前 Go 拥有成熟的 Http 处理包,所以我们去编写一个 ...
- 介绍ServiceSelf项目
ServiceSelf 做过服务进程功能的同学应该接触过Topshelf这个项目,它在.netframework年代神一搬的存在,我也特别喜欢它.遗憾的是在.netcore时代,这个项目对.netco ...