Cypress中存在多个POST请求时,如何拦截首个登录请求并排查重复请求问题?
为什么会出现两个登录请求,以及如何拦截第一个请求?
一、两个请求的原因分析
- URL编码问题导致浏览器自动修正:你第一个请求里的密码
9K%bZKR8包含未编码的%字符,而%在URL中是保留字符,必须被编码为%25(因为%是URL转义的标识,后面需要跟两位合法的十六进制数)。由于%b不是有效的转义组合(合法转义是%+0-9/A-F的两位字符),浏览器判定这个URL无效,自动对%进行转义后重新发起了第二个请求,这就是第二个请求密码变成9K%25bZKR8的核心原因。 - 前端代码的重复触发逻辑:也有可能是前端代码存在两次触发登录的逻辑——第一次发送时未对密码做URL编码,之后代码检测到错误,又重新编码密码后发送了第二次请求。
二、为什么第一个请求拦截失败?
主要有两个关键点:
- 请求被浏览器中止/取消:Cypress的
cy.intercept()默认只会捕获成功完成的HTTP请求。如果第一个请求因为URL格式错误被浏览器直接中止、取消,Cypress就不会记录这个请求,自然会提示“No request ever occurred.”。 - 拦截URL的格式错误:你硬编码的URL里使用了
&(HTML实体编码的&),但实际请求的URL参数分隔符是&,这会导致拦截规则无法匹配到真实请求。
三、如何对第一个请求进行断言?
虽然第一个请求本身是无效的,最终业务上生效的是第二个请求,但如果你确实需要对它做断言,可以尝试以下方法:
1. 修正拦截URL的格式
把拦截规则里的&替换成真实的&,确保匹配到实际请求:
cy.intercept('POST', `**/Users/Login?username=****&password=9K%bZKR8`).as('firstLoginRequest')
2. 监听所有匹配的请求(包括中止的)
使用cy.intercept()的回调函数捕获所有符合URL规则的请求,即使它们被中止。你可以在回调里判断请求参数,对第一个请求做断言:
cy.intercept('POST', '**/Users/Login', (req) => { // 检查请求的密码是否是未编码的版本 if (req.query.password === '9K%bZKR8') { // 这里添加你需要的断言 expect(req.method).to.equal('POST') expect(req.query.username).to.equal('****') } }).as('allLoginRequests') // 点击登录按钮 cy.get('[data-testid="login-button"]').click() // 获取所有捕获的请求,包括中止的 cy.get('@allLoginRequests.all').then((requests) => { // 断言第一个请求存在且参数正确 const firstRequest = requests[0] expect(firstRequest).to.exist expect(firstRequest.query.password).to.equal('9K%bZKR8') })
3. 排查并修复前端代码(推荐)
如果第一个请求是前端代码的失误导致的,建议排查并修复前端逻辑,确保只发送一次正确编码的请求。这样不仅测试会更简洁,也能避免无效请求带来的性能问题。
总结
如果你的测试目标是验证登录功能正常工作,断言第二个请求(成功完成的那个)是更合理的选择。但如果业务需求必须验证第一个请求的存在,可以通过上述方法实现。
内容的提问来源于stack exchange,提问作者user9847788
相关产品推荐
相关产品推荐

