Cypress(E2E + 组件测试)
概述
Cypress 通过一流的网络控制、时间旅行调试和强大的本地开发工作流来运行浏览器自动化。可将它用于关键路径的 E2E 测试,以及在浏览器级渲染很重要时进行组件测试。
快速开始
安装并打开:
npm i -D cypress npx cypress open
最小测试示例:
// cypress/e2e/health.cy.ts describe("health", () => { it("loads", () => { cy.visit("/"); cy.contains("Hello").should("be.visible"); }); });
核心模式
1)稳定选择器
选择器优先使用 data-testid(或 data-cy)属性。对于关键交互,避免脆弱的 CSS 链和仅依赖文本的选择器。
<button data-testid="save-user">Save</button>
cy.get('[data-testid="save-user"]').click();
2)确定性等待(避免固定休眠)
等待应用可见条件或网络别名,而不是 cy.wait(1000)。
cy.intercept("GET", "/api/users/*").as("getUser"); cy.visit("/users/1"); cy.wait("@getUser"); cy.get('[data-testid="user-email"]').should("not.be.empty");
3)使用 cy.intercept 进行网络控制
为确定性测试和速度而桩化响应。将少量“真实后端”冒烟测试单独保留。
cy.intercept("GET", "/api/users/1", { statusCode: 200, body: { id: "1", email: "a@example.com" }, }).as("getUser");
4)认证策略
优先使用 cy.session 缓存登录,以提升速度和稳定性。
// cypress/support/commands.ts Cypress.Commands.add("login", () => { cy.session("user", () => { cy.request("POST", "/api/auth/login", { email: "test@example.com", password: "password", }); }); });
// e2e spec beforeEach(() => { cy.login(); });
组件测试
运行组件测试,在保持浏览器渲染的同时隔离验证 UI 行为。
npx cypress open --component
// cypress/component/Button.cy.tsx import React from "react"; import Button from "../../src/Button";
describe("<Button />", () => { it("clicks", () => { cy.mount(<Button onClick={cy.stub().as("onClick")}>Save</Button>); cy.contains("Save").click(); cy.get("@onClick").should("have.been.calledOnce"); }); });
CI 模式
产物(视频/截图)
为失败的运行存储产物,并将视频设为可选以减少存储占用。
// cypress.config.ts import { defineConfig } from "cypress";
export default defineConfig({ video: false, screenshotOnRunFailure: true, retries: { runMode: 2, openMode: 0 }, });
并行化(Cypress Cloud)
当运行时间主导反馈循环时,可通过 Cypress Cloud 并行化较长的 E2E 测试套件。
反模式
将 cy.wait(1000) 用作同步机制。
通过深层 CSS 路径选择元素。
在同一测试文件中混合大量网络桩与“真实后端”断言。
依赖测试顺序;使用 cy.session 和每个测试的设置来隔离状态。
故障排查
症状:点击不稳定或找不到元素
操作:
为该元素添加 data-testid 钩子。
在交互前断言可见性(should("be.visible"))。
等待渲染该元素的数据对应的网络别名。
症状:测试仅在 CI 中失败
操作:
增加运行模式重试次数,并在失败时记录截图。
验证视口和 baseUrl 配置与 CI 环境匹配。
消除对仅本地种子数据的依赖;通过 API 调用创建数据。
资源
Cypress 文档:https://docs.cypress.io/
最佳实践:https://docs.cypress.io/guides/references/best-practices