如何使用Cypress对已取消的请求进行断言验证
Cypress 校验接口请求取消状态的实现方案
之前统计请求数量失效的核心原因:默认
cy.wait('@apiAlias')只会捕获正常返回响应的请求,被取消的请求不会触发wait的回调,所以统计到的数量会比实际发起的请求数少。
以下两种方案都可以直接落地,适配短时间重复请求被自动取消的业务场景:
方案1:监听abort事件精准捕获取消请求
通过拦截器的abort事件直接监听请求取消动作,不会漏记,是稳定性最高的方案:
// 定义数组存储被取消的请求记录 const cancelledRequests = [] // 拦截目标POST接口,绑定取消事件监听 cy.intercept('POST', '/你的业务接口路径*', (req) => { // 请求被前端/浏览器取消时触发该回调 req.on('abort', () => { cancelledRequests.push({ requestBody: req.body, cancelTime: Date.now() }) }) // 不要手动调用req.reply/req.continue之外的方法,避免干扰原有请求逻辑 }).as('repeatRequestApi') // 模拟短时间连续触发多次请求的操作,以下为示例,替换成你的业务触发逻辑 cy.get('#search-input').focus() for (let i = 0; i < 5; i++) { cy.get('#search-input').type(i.toString(), { delay: 20 }) } // 等待所有请求处理完成后做断言 cy.wait('@repeatRequestApi.all', { timeout: 10000 }).then(() => { // 示例断言:5次连续触发,仅最后1次请求成功,其余4次被取消 expect(cancelledRequests.length).to.equal(4) })
方案2:遍历所有请求实例校验状态
如果不想额外维护数组,可以在所有请求处理完成后,直接遍历Cypress记录的所有请求对象,通过状态字段筛选被取消的请求:
cy.intercept('POST', '/你的业务接口路径*').as('repeatRequestApi') // 触发多次请求的业务操作 // 替换为你的实际操作逻辑 cy.get('#search-input').focus() for (let i = 0; i < 5; i++) { cy.get('#search-input').type(i.toString(), { delay: 20 }) } // 等待所有请求流转完成后做断言 cy.get('@repeatRequestApi.all', { timeout: 10000 }).should((allRequests) => { // 筛选被取消的请求:状态为aborted 或者 响应状态码为0(浏览器标记取消请求的默认状态码) const cancelledList = allRequests.filter(req => req.state === 'aborted' || req.response?.statusCode === 0 ) // 筛选正常成功的请求 const successList = allRequests.filter(req => req.state === 'Complete' && req.response?.statusCode === 200 ) // 按业务逻辑断言 expect(cancelledList.length).to.equal(4) expect(successList.length).to.equal(1) })
落地注意事项
- 等待请求必须用
@别名.all格式,才能拿到所有发起过的请求(包括被取消的),单个cy.wait('@别名')只会等待成功响应的请求,会出现超时或统计遗漏 - 不要在intercept回调里手动调用
req.destroy()或者自定义返回异常响应,会覆盖业务本身的取消逻辑,导致测试结果失真 - 如果你的请求取消逻辑是基于防抖/节流实现的,超时时间需要设置为「防抖间隔 + 接口最长响应时间 + 2s缓冲」,避免请求还没处理完就执行断言
- 若使用Cypress 10以下版本出现abort事件不触发的问题,升级到Cypress 12+版本即可,低版本对AbortController的监听存在已知bug
参考场景截图:
内容的提问来源于stack exchange,提问作者Dogma Plowx
相关产品推荐
相关产品推荐

