第十二篇:《Cypress实战:从安装到第一个端到端测试》

如果说 Playwright 是"全能型选手",那么 Cypress 就是"专为现代前端应用而生"的测试工具。它直接在浏览器中运行,提供实时重载、时间旅行调试、自动等待等特性,深受 React/Vue 开发者喜爱。本文将带你快速上手 Cypress,编写第一个端到端测试,并与 Selenium/Playwright 进行对比。

一、Cypress 是什么?

Cypress 是一个基于 JavaScript 的端到端测试框架,它在浏览器内部运行测试代码,与应用程序共享同一个执行上下文。这意味着它可以直接访问 DOM、网络请求、存储,并且能够自动等待元素和断言。

核心特点:

实时重载:修改测试代码后自动重新执行。

时间旅行:鼠标悬停在每一步,可查看当时的 DOM 快照。

自动等待:无需显式等待或 sleep,自动重试断言直到超时。

网络控制:轻松 stub 和 mock 网络请求。

截图和视频:自动记录失败用例的截图和视频。

调试友好:类似 Chrome DevTools 的调试体验。

二、Cypress 与 Selenium、Playwright 对比

结论:Cypress 非常适合 前端开发者编写组件和端到端测试,尤其是单页应用(SPA)。如果你的应用需要多标签页、跨域 iframe 或 Safari 测试,则需考虑 Playwright。

三、安装与第一个测试

3.1 安装 Cypress

bash 复制代码
mkdir cypress-demo && cd cypress-demo
npm init -y
npm install cypress --save-dev

3.2 打开 Cypress 界面

bash 复制代码
npx cypress open

首次运行会创建示例测试和配置结构。

3.3 编写第一个测试

创建文件 cypress/e2e/first_test.cy.js:

javascript 复制代码
describe('百度搜索测试', () => {
  it('搜索 "Cypress" 应该返回结果', () => {
    cy.visit('https://www.baidu.com');
    // 输入关键词
    cy.get('#kw').type('Cypress 教程');
    // 点击搜索按钮
    cy.get('#su').click();
    // 断言搜索结果包含关键词
    cy.contains('Cypress 教程').should('be.visible');
  });
});

运行:

通过界面:npx cypress open,然后点击测试文件。

命令行(无头模式):npx cypress run

四、Cypress 核心语法

4.1 命令与断言(Chai + Sinon)

Cypress 使用类似 jQuery 的链式 API,所有命令都是异步但不需要 await,内部自动处理。

javascript 复制代码
// 获取元素(自动等待元素出现)
cy.get('.login-form').find('input[name="username"]');
cy.contains('登录');  // 通过文本查找

// 操作
cy.get('#username').type('admin');
cy.get('#password').type('123456{enter}');  // 按回车
cy.get('.btn').click();

// 断言(使用 should,支持链式)
cy.get('.welcome').should('contain', '欢迎回来');
cy.get('.error').should('be.visible');
cy.get('h1').should('have.text', 'Dashboard');

// 多个断言
cy.get('.result').should(($el) => {
  expect($el).to.have.length(3);
  expect($el.first()).to.contain('Cypress');
});

4.2 自动等待与超时

Cypress 会持续等待(默认 4 秒)直到断言成功,无需手动 sleep。

javascript 复制代码
// 即使结果稍后出现,也会等待
cy.get('.loading-spinner').should('not.exist');

可全局或局部修改超时时间:

javascript 复制代码
// 在配置文件 cypress.config.js 中
defaultCommandTimeout: 10000

// 或在测试中
cy.get('.slow-element', { timeout: 15000 }).should('be.visible');

4.3 网络请求 Mock(Stub)

Cypress 可以拦截并修改网络请求,非常适合独立测试前端逻辑。

javascript 复制代码
// 拦截 GET 请求并返回 mock 数据
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');

// 拦截 POST 请求并模拟响应
cy.intercept('POST', '/api/login', {
  statusCode: 200,
  body: { token: 'fake-token' }
}).as('login');

// 触发请求
cy.get('#login').click();
cy.wait('@login').its('response.statusCode').should('eq', 200);

4.4 处理 iframe(有限支持)

Cypress 默认不支持跨域 iframe,但可以通过加载 cypress-iframe 插件解决。

bash 复制代码
npm install -D cypress-iframe

在 cypress/support/e2e.js 中引入:

javascript 复制代码
import 'cypress-iframe';

使用:

javascript 复制代码
cy.frameLoaded('#myIframe');
cy.iframe().find('#username').type('admin');

4.5 自定义命令

在 cypress/support/commands.js 中添加可复用命令:

javascript 复制代码
Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login');
  cy.get('#username').type(username);
  cy.get('#password').type(password);
  cy.get('button[type="submit"]').click();
  cy.url().should('include', '/dashboard');
});

测试中使用:

javascript 复制代码
cy.login('admin', '123456');

五、测试组织与钩子

javascript 复制代码
describe('用户管理模块', () => {
  before(() => {
    // 整个 suite 只执行一次
    cy.visit('/');
  });

  beforeEach(() => {
    // 每个测试前执行
    cy.login('admin', '123');
  });

  it('创建用户', () => {
    cy.get('#createUser').click();
    // ...
  });

  it('删除用户', () => {
    // ...
  });

  afterEach(() => {
    // 每个测试后清理
  });

  after(() => {
    // 最后执行
  });
});

六、与 CI 集成(GitHub Actions 示例)

.github/workflows/cypress.yml:

yaml 复制代码
name: Cypress Tests
on: [push]
jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Cypress run
        uses: cypress-io/github-action@v5
        with:
          browser: chrome
          headless: true

七、常见坑与解决方案

元素不可见:Cypress 要求元素可见才能交互。确保没有覆盖层或动画。

跨域限制:Cypress 默认不允许访问不同域的页面。解决办法:

将测试和被测应用放在同一域。

使用 cy.origin() 命令(Cypress 10+ 支持跨域测试)。

异步数据不更新:使用 cy.wait() 等待特定网络请求完成,而非固定时间。

无法多标签页:Cypress 不支持多标签页测试。如有此需求,考虑 Playwright。

八、总结与选型建议

Cypress 的优势

调试体验极佳,时间旅行功能秒杀其他工具。

自动等待机制非常智能,测试代码简洁。

与前端开发工作流无缝集成。

局限性:

仅支持 JavaScript/TypeScript。

不原生支持多标签页、Safari 浏览器。

iframe 支持有限。

选型建议:

如果你是前端开发,测试自己的 React/Vue 应用 → Cypress 首选。

如果你需要跨浏览器(特别是 Safari)或多标签页测试 → Playwright。

如果你有大量遗留 Selenium 代码或需要 IE 测试 → Selenium。

相关推荐
wuyoula1 小时前
全新多平台电商代付商城源码
开发语言·c++·ui·小程序·php源码
xzl042 小时前
LVGL Coffee UI 接入实战:问题解决全记录
ui·rt-thread·lvgl
VBsemi-专注于MOSFET研发定制2 小时前
高端LED封装自动化产线功率MOSFET选型方案——精密、高效与可靠驱动系统设计指南
运维·单片机·自动化
Agent手记2 小时前
生产节拍混乱,在制品积压严重该怎么破解?——2026制造业柔性生产与Agent自动化实战指南
运维·人工智能·ai·自动化
ℳ₯㎕ddzོꦿ࿐2 小时前
告别手工发版:用 GitLab CI/CD 打通前后端自动化部署的“任督二脉”
ci/cd·自动化·gitlab
霍格沃兹测试学院-小舟畅学3 小时前
我用一个自定义Skill,把UI自动化维护时间从4小时压到15分钟
运维·ui·自动化
for_ever_love__3 小时前
UI学习:UITableViewCell的创建及复用机制
学习·ui·objective-c
hhb_6184 小时前
Tcl脚本自动化运维实操落地案例详解
运维·网络·自动化
摘星编程4 小时前
AI Agent 觉醒时刻:从单点工具到多Agent协作系统的范式革命
大数据·人工智能·自动化