Cypress 学习指南

# Cypress 简介

# 什么是 Cypress

一个前端测试工具

  • Cypress 能测试什么
      • E2E 测试
      • 集成测试
      • 单元测试(因为内嵌了 Mocha)
    • 任何在浏览器中运行的内容
  • Cypress 提供的一些功能
    • 时间旅行
    • 自动等待(类似 Jest 中的 wait)
      • 以同步风格的代码完成异步操作
    • 网络流量控制
    • 截屏
    • 持续集成
  • Cypress 语法设计(及内置对象)
    • jQuery + 链式调用
    • Promise(Bluebird)
    • Mocha + Chai

# 为什么要用 Cypress

# 学习 Cypress

# 概览

  • 耗时:从入门到熟悉基本概念,大约需要 8~16 小时
  • 难点:充分利用需要花一定时间学习和配置(报告、覆盖率、CI 等)
  • 工具:cypress

# 学习路线

  • 前置学习
  • 学习 Cypress
    • 了解 Cypress 的组成,全面阅读文档
    • 掌握基本使用
  • 实战
    • 在业务中编写测试
      • 进一步熟悉各 API 的大量细节
    • 为项目调整 Cypress 配置,使用高级功能

# 资料

# 自学教材

# 实战

# Cypress 知识体系

# Cypress 概览

# 安装/初始化

# 在已有项目中安装 cypress
npm install cypress --save-dev

# 接着运行这个命令,cypress 将初始化并生成一堆用例
npx cypress open

# 文件结构

  • /cypress
    • /fixtures (mock 数据)
      • example.json
    • /integration (测试文件)
      • /examples
        • example.spec.js (一般格式为 *.spec.js
    • /plugins (用于配置安装的 插件,task 系统)
      • index.js
    • /support (用于调整 自定义选项
      • commands.js
      • index.js
    • /screenshots (默认截屏文件夹)
  • cypress.json

# 测试文件 典型代码

///  <reference types="cypress" />

describe('描述', () => {
  before(() => console.log('---- Test Start! ----'));
  beforeEach(() => cy.visit('https://witch.url'));
  afterEach(() => cy.clearCookies());

  it('测试用户交互', () => {
    cy.get('#app')
      .children('.intro')
      .click();
    cy.contains('Welcome').should('be.exist');
  });

  it('测试显示文本', () => {
    cy.get('div').should('have.text', 'Hello');
    // * 另一种风格
    cy.get('div').should(($div) => {
      const text = $div.text();
      expect(text).to.match(/hello/i);
    });
  });
});

大致分为几个部分

  • TypeScript 自动完成支持(第一行的注释)
  • 运行器和生命周期(describeitbefore 等)
  • 元素查找和操作(cy 相关命令)
  • 断言/测试(shouldexpectassert 多种风格)

# Cypress 对象

Cypresscy 的区别

# 测试/断言

Cypress 中内置的断言 包含了几种类型:

  • Chai:断言
    • expect('test').to.be.a('string'):BDD 风格
    • assert.equal(3, 3, 'vals equal'):TDD 风格
  • Chai jQuery:关于 DOM 的断言
    • expect(\$el).to.have.attr('foo', 'bar')
  • Sinon-Chai:关于函数调用情况的断言
    • expect(spy).to.be.called
  • .should():在 Cypress 中封装了以上所有可用断言
    • cy.get('li.selected').should('have.length', 3):should
    • cy.get('div').should(($div) => { expect($div)... }):BDD

注意到 Cypress 使用 Mocha BDD 风格的生命周期
不同测试的命名风格:

Mocha BDD Mocha TDD Jest
describe/context suite describe
specify/it test test/it
before setup beforeAll
after teardown afterAll
beforeEach suiteSetup before
afterEach suiteTeardown after

# cy 命令

用来编写测试

  • 测试
    • should:断言
    • then:类似 Promise 的 then
    • each:遍历执行(对于数组)
    • spread:then 的 each 版
  • 查询
    • containsget
      • childrenclosestfind
      • eqfilternot
      • firstlast
      • nextnextAllnextUntil
      • parentparentsparentsUntil
      • prevprevAllprevUntil
      • siblings
    • windowdocumenttitle
    • its:取得对象中的字段,如 cy.get('ul li').its('length')
    • root:当前上下文的根元素节点
    • within:设定上下文元素(类似 JS 中的 with)
  • 操作
    • 用户操作
      • clickdblclickrightclick
      • blurfocusfocused
      • hover:不支持
      • trigger:触发事件
    • 表单/输入框
      • checkuncheckselect
      • clear:清除文本框
      • type:输入文本框
      • submit
    • scrollIntoViewscrollTo
    • invoke:调用对象中的函数,如 cy.get('div').invoke('show')
  • 浏览器
    • viewport:设置应用窗口大小
    • clearCookieclearCookiesgetCookiegetCookiessetCookie
    • clearLocalStorage
  • 网络请求
    • visitreload:访问
    • hashlocationurl:获取
    • go:历史跳转,相当于 window.history.go
    • request:HTTP 请求
    • server:启动一个服务
    • route:跳转路由
  • 功能性
    • 任务
      • logdebugpause
      • exec:执行 shell 命令
      • readFilewriteFile
      • screenshot:截屏到 /screenshots
      • fixture:读取 /fixtures 中文件内容
      • task:执行 /plugins 中声明的事件
    • 语法糖
      • as:设置为别名
      • and:进行多个测试
      • end:截断当前测试(后续链式调用将重新计算)
      • wrap:包装一个对象(以便支持 cy 命令)
    • 调用监听
      • spy:监听对象中的函数
      • stub:替换对象中的函数(用于监听)
    • Timer
      • clock:覆写原生时钟(将会影响 setTimeout 等原生函数)
      • tick:跳过时间,加快测试速度(需要先 cy.clock()
      • wait:显式等待(不推荐使用)

# Cypress API

包含定制选项方法,或公共静态方法

  • 定制
    • Commands:添加自定义命令
    • Cookies:测试时的 Cookie 行为控制
    • Screenshot:截屏参数配置
    • SelectorPlayground:调整选择器规则
    • Server:调整 cy.server() 默认参数
    • config:修改 Cypress 的 配置选项
    • env:管理自定义全局变量
    • log:配置 log 参数
  • 辅助
    • dom:一组 dom 相关方法
      • Cypress.dom.isHidden($el)
    • isCy:是否是 cy 对象
  • 环境信息
    • arch:获取 CPU 架构,来源于 Node os.arch()
    • browser:获取浏览器信息
    • platform:获取操作系统名字
    • spec:当前测试文件信息
    • version:版本号

# 事件

事件绑定机制是 Node Events
用法如:Cypress.on/cy.on

  • 应用(页面)事件
    • uncaught:exception
    • window:confirmwindow:alertwindow:before:loadwindow:loadwindow:before:unloadwindow:unload
    • url:changed
  • Cypress 事件
    • fail
    • viewport:changed
    • scrolled
    • command:enqueuedcommand:startcommand:endcommand:retry
    • log:addedlog:changed
    • test:before:runtest:after:run

# Cypress 典型代码

查看上文中的 实战链接典型代码