中文

一份关于强大的端到端测试框架 Cypress 的综合指南,内容涵盖安装、编写测试、调试、CI/CD 集成以及最佳实践。

Cypress:Web 应用终极端到端测试指南

在当今快速发展的 Web 开发领域,确保 Web 应用的质量和可靠性至关重要。端到端(E2E)测试在从用户角度验证应用所有组件能否无缝协同工作方面扮演着关键角色。Cypress 已成为领先的 E2E 测试框架,它提供了对开发者友好的体验、强大的功能和卓越的性能。本综合指南将引导您了解开始使用 Cypress 并有效测试您的 Web 应用所需的一切知识。

什么是 Cypress?

Cypress 是为现代 Web 构建的下一代前端测试工具。与在浏览器中运行测试的传统测试框架不同,Cypress直接在浏览器中运行,让您对应用的行为拥有无与伦比的控制力和可见性。它的设计宗旨是快速、可靠且易于使用,这使其成为全球开发者和 QA 工程师的热门选择。Cypress 使用 JavaScript 编写并在浏览器内执行,这使其性能非常高,并能提供对应用内部无与伦比的访问权限。

使用 Cypress 的主要优势

安装与设置

开始使用 Cypress 非常简单。以下是安装方法:

  1. 先决条件: 确保您的系统上已安装 Node.js 和 npm(Node 包管理器)。您可以从 Node.js 官网下载它们。
  2. 安装 Cypress: 打开您的终端或命令提示符,导航到您的项目目录,并运行以下命令:
  3. npm install cypress --save-dev
  4. 打开 Cypress: 安装完成后,您可以通过运行以下命令打开 Cypress 测试运行器:
  5. npx cypress open

    此命令将启动 Cypress 测试运行器,它提供了一个用于运行和调试测试的图形界面。

编写您的第一个 Cypress 测试

让我们创建一个简单的测试来验证网站主页是否能正确加载。在您项目的 `cypress/e2e` 目录下创建一个名为 `example.cy.js` 的新文件。


// cypress/e2e/example.cy.js

describe('My First Test', () => {
  it('Visits the Kitchen Sink', () => {
    cy.visit('https://example.cypress.io')
    cy.contains('type').click()
    cy.url().should('include', '/commands/actions')

    cy.get('.action-email')
      .type('fake@email.com')
      .should('have.value', 'fake@email.com')
  })
})

让我们来分解一下这个测试:

在 Cypress 测试运行器中运行此测试以查看其效果。您应该会看到浏览器导航到 Cypress Kitchen Sink 网站,点击 “type” 链接,并验证 URL。

Cypress 命令

Cypress 提供了广泛的命令用于与您的应用进行交互。以下是一些最常用的命令:

这些只是 Cypress 中众多可用命令的一部分。有关命令及其选项的完整列表,请参阅 Cypress 文档。

Cypress 中的断言

断言用于验证您的应用的预期行为。Cypress 提供了一套丰富的内置断言,您可以用它来检查元素的状态、URL、标题等。断言使用 `.should()` 方法链接在 Cypress 命令之后。

以下是一些常见的断言示例:

您还可以创建自定义断言以满足您的特定需求。

编写 Cypress 测试的最佳实践

遵循最佳实践可以帮助您编写更易于维护、更可靠、更高效的 Cypress 测试。以下是一些建议:

Cypress 高级技巧

桩件 (Stubbing) 与模拟 (Mocking)

Cypress 允许您对网络请求和响应进行打桩,从而能够模拟不同场景并测试应用的错误处理能力。这对于测试依赖外部 API 或服务的功能特别有用。

要对网络请求进行打桩,您可以使用 `cy.intercept()` 命令。例如,下面的代码对 `/api/users` 的 GET 请求进行打桩,并返回一个模拟响应:


cy.intercept('GET', '/api/users', {
  statusCode: 200,
  body: [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' }
  ]
}).as('getUsers')

然后,您可以使用 `cy.wait('@getUsers')` 等待被拦截的请求,并验证您的应用是否正确处理了模拟响应。

处理 Local Storage 和 Cookies

Cypress 提供了与 local storage 和 cookies 交互的命令。您可以在测试中使用这些命令来设置、获取和清除 local storage 和 cookies。

要设置一个 local storage 项,您可以使用 `cy.window()` 命令访问 window 对象,然后使用 `localStorage.setItem()` 方法。例如:


cy.window().then((win) => {
  win.localStorage.setItem('myKey', 'myValue')
})

要获取一个 local storage 项,您可以使用 `cy.window()` 命令,然后使用 `localStorage.getItem()` 方法。例如:


cy.window().then((win) => {
  const value = win.localStorage.getItem('myKey')
  expect(value).to.equal('myValue')
})

要设置一个 cookie,您可以使用 `cy.setCookie()` 命令。例如:


cy.setCookie('myCookie', 'myCookieValue')

要获取一个 cookie,您可以使用 `cy.getCookie()` 命令。例如:


cy.getCookie('myCookie').should('have.property', 'value', 'myCookieValue')

处理文件上传

Cypress 提供了一个名为 `cypress-file-upload` 的插件,可以简化测试中的文件上传操作。要安装该插件,请运行以下命令:

npm install -D cypress-file-upload

然后,将以下行添加到您的 `cypress/support/commands.js` 文件中:


import 'cypress-file-upload';

然后您就可以使用 `cy.uploadFile()` 命令来上传文件。例如:


cy.get('input[type="file"]').attachFile('example.txt')

处理 IFrame

测试 IFrame 可能有些棘手,但 Cypress 提供了一种与之交互的方法。您可以使用 `cy.frameLoaded()` 命令等待 IFrame 加载完成,然后使用 `cy.iframe()` 命令获取 IFrame 的 document 对象。


cy.frameLoaded('#myIframe')
cy.iframe('#myIframe').find('button').click()

Cypress 与持续集成/持续部署 (CI/CD)

将 Cypress 集成到您的 CI/CD 管道中对于确保应用质量至关重要。您可以在 CI/CD 环境中以无头模式运行 Cypress 测试。方法如下:

  1. 安装 Cypress: 确保 Cypress 作为项目依赖项安装。
  2. 配置 CI/CD: 配置您的 CI/CD 管道,在每次构建后运行 Cypress 测试。
  3. 无头模式运行 Cypress: 使用 `cypress run` 命令以无头模式运行 Cypress 测试。

CI/CD 配置示例(使用 GitHub Actions):


name: Cypress Tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
      - name: Install dependencies
        run: npm install
      - name: Cypress run
        uses: cypress-io/github-action@v5
        with:
          start: npm start
          wait-on: 'http://localhost:3000'

此配置将在代码被推送到 `main` 分支或针对 `main` 分支创建拉取请求时运行 Cypress 测试。`cypress-io/github-action` 这个 action 简化了在 GitHub Actions 中运行 Cypress 测试的过程。

调试 Cypress 测试

Cypress 提供了出色的调试工具,帮助您识别和修复测试中的问题。以下是一些调试 Cypress 测试的技巧:

Cypress 与其他测试框架的比较

虽然 Cypress 是一个强大的端到端测试框架,但了解它与其他流行选项的比较至关重要。以下是简要概述:

框架的选择取决于您项目的具体需求和要求。对于需要快速、可靠且对开发者友好的端到端测试的现代 Web 应用来说,Cypress 是一个绝佳的选择。

Cypress 实战示例

让我们探讨几个真实世界的例子,看看如何使用 Cypress 测试不同类型的 Web 应用:

测试电子商务应用

您可以使用 Cypress 来测试电子商务应用中的各种用户流程,例如:

以下是一个 Cypress 测试示例,用于验证用户可以成功将产品添加到购物车:


it('Adds a product to the cart', () => {
  cy.visit('/products')
  cy.get('.product-card').first().find('button').click()
  cy.get('.cart-count').should('have.text', '1')
})

测试社交媒体应用

您可以使用 Cypress 来测试社交媒体应用中的用户交互,例如:

以下是一个 Cypress 测试示例,用于验证用户可以成功创建新帖子:


it('Creates a new post', () => {
  cy.visit('/profile')
  cy.get('#new-post-textarea').type('Hello, world!')
  cy.get('#submit-post-button').click()
  cy.get('.post').first().should('contain', 'Hello, world!')
})

测试银行应用

对于银行应用,Cypress 可用于测试关键功能,例如:

一个验证资金转移的测试可能如下所示(为安全起见,使用了适当的打桩):


it('Transfers funds successfully', () => {
  cy.visit('/transfer')
  cy.get('#recipient-account').type('1234567890')
  cy.get('#amount').type('100')
  cy.intercept('POST', '/api/transfer', { statusCode: 200, body: { success: true } }).as('transfer')
  cy.get('#transfer-button').click()
  cy.wait('@transfer')
  cy.get('.success-message').should('be.visible')
})

结论

Cypress 是一个功能强大且用途广泛的端到端测试框架,可以帮助您确保 Web 应用的质量和可靠性。其对开发者友好的 API、强大的功能和卓越的性能使其成为全球开发者和 QA 工程师的热门选择。通过遵循本指南中概述的最佳实践,您可以编写出有效的 Cypress 测试,帮助您在开发过程的早期发现错误,并向用户交付高质量的软件。

随着 Web 应用的不断发展,端到端测试的重要性只会与日俱增。拥抱 Cypress 并将其集成到您的开发工作流程中,将使您能够构建更健壮、更可靠、更友好的 Web 用户体验。