Cypress入门

What

Cypress是一款基于javascript的开源端到端测试框架。与大家比较熟悉的jmeter等基于网络请求自动化测试框架不同,cypress可以运行在各种浏览器上,包括chrome,firfox等,通过控制浏览器行为,对网页UI元素进行自动化测试。

安装

推荐使用npm方式进行安装。虽然cypress提供了安装包,但是测试case是基于nodejs进行运行编写,所以相关环境是逃不掉的。

1. 安装nodejs

通过官网根据系统选择下载对应版本,LTS为长期支持版本(Long Term Support),Current为最新开发版本,推荐使用LTS版本。
下载后一路next即可

https://nodejs.org/en/

安装完成后通过命令行查看安装是否成功。

1
node -v

nodejs安装完成后会自带npm,及node的包管理工具。

1
npm -v

2. 通过npm安装cypress

1
npm install cypress --save-dev

--save-dev 表示下载至当前项目目录,而非全局。并且仅在dev模式下使用,生产环境不需要

test-cypress-00

TIPS: 如果下载速度较慢,可以改动taobao提供的NPM镜像进行下载。

https://npmmirror.com/

1
npm install -g cnpm --registry=https://registry.npmmirror.com

之后使用 cnpm 替换 npm 执行下载动作

3. 打开cypress

安装命令执行后,多了一个node_modules目录,相关的镜像依赖都在这个目录下,可以到对应的cypress目录下执行相关命令,如 open 可以打开cypress UI控制面,运行一个默认的TODO页面测试case

1
./node_modules/cypress/bin/cypress open

test-cypress-01

运行case会打开一个Chrome浏览器,对比case与实际浏览器展示效果。

test-cypress-02

使用

以baidu网站登陆功能为例,测试用例为

  1. 访问 https://www.baidu.com
  2. 页面包含登录按钮并单击
  3. 弹窗中不包含“请您输入手机号/用户名/邮箱”
  4. 单击弹窗中登录按钮
    1. 提示“请您输入手机号/用户名/邮箱”
  5. 在username表单输入框中输入abc
  6. 单击弹窗中登录按钮
    1. 提示“请您输入密码”
  7. 在passport表单输入框中输入123
  8. 单击弹窗中登录按钮
    1. 错误内容包含“用户名或密码有误,请重新输入或”

编写测试用例

cypress/integration 目录新建baidu.js文件用于编写行为代码及预期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
describe('百度', () => {
beforeEach(() => {
cy.visit('https://www.baidu.com')
})
it('首页登录', () => {
cy.get('#s-top-loginbtn')
.should('have.text', '登录')
.click()

cy.get('#passport-login-pop-api .pass-text-input.pass-text-input-userName')
.should('not.have.value', 'abc')

cy.get('#TANGRAM__PSP_11__submit')
.click({ force: true })

cy.contains('请您输入手机号/用户名/邮箱')

cy.get('#passport-login-pop-api .pass-text-input.pass-text-input-userName')
.type('abc')
.should('have.value', 'abc')


cy.get('#passport-login-pop-api .pass-button.pass-button-submit')
.click({ multiple: true, force: true })

cy.contains('请您输入密码')

cy.get('#TANGRAM__PSP_11__password')
.type('123')

cy.get('#TANGRAM__PSP_11__submit')
.click({ force: true })

cy.get('#TANGRAM__PSP_11__error')
.contains('用户名或密码有误,请重新输入或')
.should('have.css', 'display')

})
})

可以通过 open 打开可视化页面,单击baidu.js用例运行测试用例

1
./node_modules/cypress/bin/cypress open

也可以直接在命令行运行

1
./node_modules/cypress/bin/cypress run

如果运行失败,则会在screenshots目录保存失败截图,及videos目录保存运行视频。

test-cypress-03

test-cypress-04

录制生成用例

可以通过录制方式快速生成行为代码。

  1. 在cypress.json文件中开启experimentalStudio功能
1
2
3
4
{
"projectId": "3y3u55",
"experimentalStudio": true
}

在cypress中可以确认experimentalStudio变为true

test-cypress-05

在cypress/integration/中新建baidu-auto.js文件。输入下列内容,只需声明开启时访问https://www.baidu.com 并创建Login用例

1
2
3
4
5
6
7
describe('baidu', function () {
beforeEach(() => {
cy.visit('https://www.baidu.com')
})
it("Login", function () {
})
})

通过open启动cypress并运行baidu-auto.js用例,在开启的chrome浏览器中Login用例开启 Add Commands toTest

test-cypress-06

在右侧浏览器中进行操作,左侧用例会实时生成对应的行为命令,单击 Save Commands 按钮,命令将保存在juenjin.js文件中

test-cypress-07

查看baidu-auto.js文件,可以看到行为代码已生成,可以在此基础上编写预期代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
describe('baidu', function () {
beforeEach(() => {
cy.visit('https://www.baidu.com')
})
it("Login", function () {
/* ==== Generated with Cypress Studio ==== */
cy.get('#s-top-loginbtn').click();
cy.get('#TANGRAM__PSP_11__submit').click();
cy.get('#TANGRAM__PSP_11__userName').clear();
cy.get('#TANGRAM__PSP_11__userName').type('abc');
cy.get('#TANGRAM__PSP_11__submit').click();
cy.get('#TANGRAM__PSP_11__password').clear();
cy.get('#TANGRAM__PSP_11__password').type('123');
cy.get('#TANGRAM__PSP_11__submit').click();
/* ==== End Cypress Studio ==== */
})
})

集成CI

实际使用过程中,需要和各种CICD工具进行集成。
Jenkins

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
pipeline {
agent {
// this image provides everything needed to run Cypress
docker {
image 'cypress/base:10'
}
}

stages {
stage('build and test') {
environment {
// we will be recording test results and video on Cypress dashboard
// to record we need to set an environment variable
// we can load the record key variable from credentials store
// see https://jenkins.io/doc/book/using/using-credentials/
CYPRESS_RECORD_KEY = credentials('cypress-example-kitchensink-record-key')
}

steps {
sh 'npm ci'
sh "npm run test:ci:record"
}
}
}
}

Gitlab CI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
stages:
- test

cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/

test:
image: cypress/browsers:node12.14.1-chrome85-ff81
stage: test
script:
# install dependencies
- npm ci
# start the server in the background
- npm run start:ci &
# run Cypress tests
- npx cypress run --browser firefox
artifacts:
when: always
paths:
- cypress/videos/**/*.mp4
- cypress/screenshots/**/*.png
expire_in: 1 day

1