游乐游手机版
首页/AI教程/文章详情

Cypress API测试入门:使用cy.request()测试接口方法

时间:2026-08-15 13:27
你已经使用 Cypress 运行端到端测试了。现在你想直接调用 API、检查状态码并对 JSON body 进行断言,而无需通过 UI 界面进行点击操作。Cypress 完全可以做到这一点。cy request() 命令从浏览器外部的 Node 进程发送真实的 HTTP 请求,因此你可以单独测试某个

你已经使用 Cypress 运行端到端测试了。现在你想直接调用 API、检查状态码并对 JSON body 进行断言,而无需通过 UI 界面进行点击操作。Cypress 完全可以做到这一点。cy.request() 命令从浏览器外部的 Node 进程发送真实的 HTTP 请求,因此你可以单独测试某个接口,或者在 UI 测试运行之前进行状态初始化。

本指南将向你展示如何使用 Cypress 进行 API 测试:包括 cy.request() 的基础用法、对响应进行断言、链式调用请求以复用 auth Token,以及使用 cy.intercept() 拦截和模拟浏览器流量。你还将了解到 Cypress 在 API 测试中的适用场景,以及在什么情况下使用原生 API 工具更为合适。

为什么使用 Cypress 测试 API

大多数 Cypress 测试套件都是驱动浏览器运行的。但你在 UI 中验证的很多内容,本质上都是底层的 API:例如 /login 是否返回了 Token,/users 返回的数据结构是否正确,POST 请求是否创建了预期的记录。

直接测试这些接口有两个好处。首先,API 检查的运行速度比 UI 流程更快,因为没有页面渲染,也不需要等待元素加载。其次,你可以使用 cy.request() 来初始化测试数据。无需通过点击注册表单来创建用户,只需发送一个 POST 请求,然后直接进入你真正关心的断言步骤。

如果你的技术栈中已经包含了 Cypress,那么添加 API 测试就意味着无需安装任何新工具。你可以在同一个测试文件中编写它们,使用相同的 expect 断言,并在同一个 CI 流程中运行。

cy.request() 基础知识

cy.request() 用于发送 HTTP 请求并获取响应。它在 Cypress 的 Node 进程中运行,而不是在浏览器中运行,因此不受 CORS 或同源策略的限制。

该命令支持以下几种调用形式:

cy.request(url)cy.request(url, body)cy.request(method, url)cy.request(method, url, body)cy.request(options)

最简单的调用方式是传入一个 URL。如果没有指定方法,Cypress 默认会使用 GET:

cy.request('https://jsonplaceholder.typicode.com/users')

对于除基本 GET 之外的其他操作,可以传入一个 options object。这让你能够完全控制方法、body 和 headers:

cy.request({method: 'POST',url: 'https://jsonplaceholder.typicode.com/posts',headers: {'Content-Type': 'application/json'},body: {title: 'API test',body: 'created from Cypress',userId: 1}})

该 object 中常用的配置项包括:

  • method:HTTP 请求方法(GET、POST、PUT、PATCH、DELETE 等)。默认为 GET。
  • url:接口地址。必填项。
  • body:请求的 payload。Cypress 会自动将对象序列化为 JSON。
  • headers:请求 header 的 object。
  • auth:用于 HTTP 基础认证(Basic Authentication)的凭证。
  • qs:以 object 形式表示的查询字符串参数(query string parameters)。
  • failOnStatusCode:当你想要对 4xx 或 5xx 响应进行断言而不是直接让测试失败时,将此项设置为 false。

最后一个选项对于异常测试非常重要。默认情况下,如果收到任何非 2xx 或 3xx 的状态码,cy.request() 都会使测试失败。如果你要验证一个错误的请求是否返回 400,你需要禁用此默认行为:

cy.request({method: 'GET',url: 'https://jsonplaceholder.typicode.com/users/99999',failOnStatusCode: false}).then((response) => {expect(response.status).to.eq(404)})

断言 status 和 body

cy.request() 调用完成后,会返回一个响应对象,后续通常通过链式的 .then() 来拿到这个结果并继续处理。这个响应里,最常打交道的通常就是下面四个属性:

  • status:HTTP 状态码。
  • body:响应 payload。当 Content-Type 以 json 结尾时,Cypress 会自动将其解析为 Ja vaScript 对象。
  • headers:响应 header。
  • duration:请求耗时(毫秒)。

以下是一个完整的测试,用于验证 status、body 结构以及特定字段:

describe('Users API', () => {it('returns a list of users', () => {cy.request('https://jsonplaceholder.typicode.com/users').then((response) => {expect(response.status).to.eq(200)expect(response.body).to.be.an('array')expect(response.body).to.ha ve.length(10)expect(response.body[0]).to.ha ve.property('email')})})})

由于 response.body 已经是一个解析后的对象,你可以使用标准的 Chai 对其进行断言。你可以验证类型、长度、嵌套属性或具体的值。这与你用于 UI 测试的断言语法完全相同,因此无需学习新概念。

你也可以对响应 header 进行断言,这在验证内容类型或缓存设置时非常有用:

cy.request('https://jsonplaceholder.typicode.com/users').then((response) => {expect(response.headers['content-type']).to.include('application/json')})

欲深入了解如何构建这些校验,请参阅我们的 API 断言指南以及更广泛的 API 测试最佳实践。

链式请求与复用 auth Token

真实的 API 通常需要身份验证。常见的模式是登录一次,获取 Token,然后在其后的每个请求中发送该 Token。cy.request() 的链式调用非常适合处理这种场景。

发送登录请求,从响应 body 中读取 Token,然后在下一次调用中使用它:

describe('Authenticated API flow', () => {it('logs in and fetches a protected resource', () => {cy.request({method: 'POST',url: 'https://api.example.com/login',body: {email: 'user@example.com',password: 'secret'}}).then((loginResponse) => {expect(loginResponse.status).to.eq(200)const token = loginResponse.body.tokency.request({method: 'GET',url: 'https://api.example.com/profile',headers: {Authorization: `Bearer ${token}`}}).then((profileResponse) => {expect(profileResponse.status).to.eq(200)expect(profileResponse.body).to.ha ve.property('email', 'user@example.com')})})})})

如果多个测试需要相同的 Token,可以将登录逻辑移入 beforeEach 中,并使用 Cypress.env() 或封装的别名(alias)来存储 Token,以便每个测试都能获取到它。这样可以将 auth 设置集中在一处,而无需在每个 spec 中重复编写。

这种“先登录后使用”的模式与你在编写任何 API 集成测试流程时的逻辑完全一致,即一个调用产生的数据会传递给下一个调用。

使用 cy.intercept() 进行存根模拟

cy.request() 会向真实的 API 发送请求。有时你可能需要相反的操作:拦截前端应用发出的请求,并返回一个虚假的响应。这就是 cy.intercept() 的作用。

这里有一个重要的区别。cy.intercept() 仅拦截前端应用在浏览器中发出的请求。它不会拦截 cy.request(),因为 cy.request() 完全绕过了浏览器。当你需要测试 UI 如何对给定的 API 响应做出反应时,请使用 cy.intercept(),而不是在测试 API 本身时使用。

你可以监听(spy)请求、使用静态响应进行模拟(stub),或者等待它。要进行模拟,只需传入一个响应 object:

ja vascript cy.intercept('GET', '/api/users', { statusCode: 200, body: [{ id: 1, name: 'Ada' }] })

这样一来,浏览器里所有发往 /api/users 的请求,都会直接拿到这份固定的 payload。它的价值就在这里:那些在真实后端里不太容易稳定复现的边界场景,现在都能主动验证了,比如空列表、500 错误,或者响应明显变慢的情况。

要断言该请求已发生,可以使用 .as() 为其设置别名并等待它:

ja vascript it('shows an error banner when the API fails', () => { cy.intercept('GET', '/api/users', { statusCode: 500, body: { message: 'Server error' } }).as('getUsers')cy.visit('/dashboard') cy.wait('@getUsers').its('response.statusCode').should('eq', 500) cy.contains('Something went wrong').should('be.visible') })

cy.wait('@getUsers') 这行代码会暂停测试,直到拦截的请求完成解析,然后将请求和响应传给你以进行断言。请务必在触发请求的操作之前设置拦截,否则它将无法捕获任何内容。如果你正在权衡何时模拟响应与 mock 整个服务,我们关于 API mocking 以及 API stubbing vs API mocking 的文章中详细分析了各自的利弊。

何时适合使用 Cypress 进行 API 测试,何时不适合

Cypress 非常适合嵌入在 UI 测试套件中的 API 检查。如果你已经在编写端到端测试,并且需要播种(seed)数据、验证 UI 依赖的接口,或者通过模拟响应来测试错误处理,cy.request() 和 cy.intercept() 可以将所有内容集中在同一个地方。无需切换上下文,也无需引入第二个工具。

如果 Cypress 是你唯一的测试 runner,并且你不想添加其他依赖项,那么用它来进行少量独立的 API 冒烟测试也是完全可以的。

但如果是针对大型的、独立的 API 测试套件,情况就会变得有些尴尬。Cypress 是专为浏览器构建的,因此 API 测试只是在其上附加的一项功能,而非核心设计。随着测试套件的增长,会出现一些不足之处:

  • 没有可视化的请求构建器。每个请求都是代码。当你有数百个接口时,手动编写 header、body 和 query 参数会变得很慢。
  • 对于仅在 CI 中运行的 API 流水线来说较为逊色。Cypress 即使对于纯 API 运行也会启动浏览器上下文,这会带来不必要的开销。
  • 没有共享的 API 定义。请求的结构存在于你的测试文件中,而不是存在于团队可以在设计、文档和测试中复用的规范中。

这就是 API 原生工具更合适的地方。Apifox 是围绕 API 本身构建的:你只需设计一次接口,然后使用可视化请求构建器和可视化断言来针对它构建测试场景,常见情况下无需编写代码。请求、环境和 auth 都保存在共享工作区中,因此你的团队无需从测试文件中重新推导它们。

对于 CI,Apifox CLI 可以在任何能运行 Node 的步骤中无头运行你保存的测试场景:

npm install -g apifox-cliapifox run --access-token "$APIFOXACCESSTOKEN" -t -e -r cli,html,junit

-t 参数指向已保存的场景或套件,-e 选择一个环境,而 -r 挑选报告格式(cli、html、json、junit)。JUnit 输出可以直接接入大多数 CI 仪表盘。添加 -d 或 --iteration-data 可以使用数据文件来驱动测试,而 --upload-report 可以将结果推送回你的工作区。CLI 运行的是已保存的场景,它不是一个交互式的请求发送器。

一个好记的思考方式是:对于支持浏览器测试的 API 检查,使用 cy.request();当 API 测试是主要工作时,选择 API 原生工具。如果你正在对比各种选择,我们收集的在 CI/CD 中运行的 API 测试自动化工具以及更广泛的 30 个最佳 API 测试工具涵盖了这一领域。

常见问题

cy.request() 是在浏览器中运行吗?

不。cy.request() 运行在 Cypress Node 进程中,处于浏览器外部。这就是为什么它不会被 CORS 或同源策略阻止,以及为什么 cy.intercept() 无法拦截它的原因。如果你需要浏览器发出的请求,请通过你的应用触发它并使用 cy.intercept() 进行捕获。

如何在不导致测试失败的情况下测试 400 或 404 响应?

默认情况下,cy.request() 会在任何非 2xx 或非 3xx 状态码时报错导致测试失败。请在选项对象中设置 failOnStatusCode: false,然后自己对状态进行断言,例如 expect(response.status).to.eq(404)。

我可以使用 cy.request() 在 UI 测试之前进行登录吗?

可以,而且这是一个很常见的模式。使用 cy.request() 向你的登录接口发送一个 POST 请求,从 response.body 中读取 Token,并将其存储(在 Cypress.env()、localStorage 或 cookie 中),这样你的 UI 测试在开始时就已经完成了身份验证。这可以跳过登录表单并提高套件的运行速度。

cy.request() 和 cy.intercept() 之间有什么区别?

cy.request() 发送真实的 HTTP 请求并返回实际的响应,因此你可以用它来测试 API。cy.intercept() 则是监听或模拟前端在浏览器中发出的请求,因此你可以用它来控制 UI 接收到的内容。前者直接访问网络,后者则对网络请求进行拦截和塑造。

我应该使用 Cypress 还是专门的 API 测试工具?

当 API 检查是为了辅助你现有的浏览器测试套件时,可以使用 Cypress。但对于大型的独立 API 套件、仅在 CI 运行的 API 流水线,或者整个团队共同协作的共享 API 定义,像 Apifox 这样原生支持 API 的工具会更加合适。请参阅我们的 API 测试最佳实践以了解如何进行选择。

开发必备:API 全流程管理神器 Apifox

介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。

如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

Cypress API 测试:如何使用 cy.request() 测试 API

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。

来源:https://apifox.com/apiskills/cypress-api-ce-shi-ru-he-shi-yong-cy-request-ce-shi-api/
上一篇Karate API测试DSL实战指南与自动化测试入门 下一篇ApacheBench终端API压力测试方法与实战指南
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
CAD零基础入门教程:坐标输入、图层管理与基础绘图命令
AI教程 · 2026-09-01

CAD零基础入门教程:坐标输入、图层管理与基础绘图命令

本文面向CAD零基础学习者,系统讲解坐标输入、图层管理与基础绘图命令的核心用法。通过分步实操与常见问题排查,帮助新手建立精确绘图习惯,掌握规范出图的基础能力。

CAD从入门到项目交付:绘图、标注、图块与实战工作流
AI教程 · 2026-09-01

CAD从入门到项目交付:绘图、标注、图块与实战工作流

掌握CAD的核心在于建立“画得准、标得清、复用快、交付稳”的工作流。本文提供从环境设置、高频命令组合、标注规范、图块标准化到项目分阶段交付的完整路径,帮助初学者避免常见返工陷阱,独立完成可检查、可复用、可打印的工程图纸。

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤
AI教程 · 2026-09-01

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤

本文详细解析 Claude Code 登录前的账号类型区分方法,涵盖个人订阅、Teams 席位与企业 Enterprise 席位的授权路径差异。提供终端登录命令、环境变量排查及常见异常处理步骤,帮助用户快速完成正确授权并避免登录路径混淆。

Claude Code 文件修改前的权限模式配置与命令审批指南
AI教程 · 2026-09-01

Claude Code 文件修改前的权限模式配置与命令审批指南

本文详细介绍Claude Code在修改文件前的权限模式配置方法,包括defaultMode可选值、permissions allow与deny规则设置、多层级配置文件管理以及 status验证技巧,帮助开发者安全高效地使用AI编程助手。

Claude Code接入VS Code后先测扩展和终端命令
AI教程 · 2026-09-01

Claude Code接入VS Code后先测扩展和终端命令

在VS Code中接入Claude Code后,建议优先验证扩展面板与集成终端两条入口。本文提供标准检查顺序、关键命令与常见故障排查路径,帮助你快速确认环境就绪,避免后续开发受阻。