第十二篇:《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。

相关推荐
qq_426003964 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
大蓝头4 天前
安装包UI美化之路-nsNiuniuSkin全新UI调试与预览方法
ui·electron·安装包·截图控件·截屏控件
慧都小项4 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
森叶4 天前
用远程调试端口自动化 Chrome 应用商店发布:做法、三个真坑,以及你必须知道的风险
自动化
懂软件的胡子个哥4 天前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发
jingli94 天前
多平台多店铺客服怎么统一接待?千牛/拼多多/抖音/京东/闲鱼/微信/快手切窗口太累,一个后台集中接管的七步落地方案(2026 实操版)
人工智能·自动化·用户运营
坚定信念,勇往无前4 天前
Playwright 的本质
自动化·网络爬虫