Cypress项目中循环调用API获取非空OTPCode失效问题求助
在Cypress中循环调用API直到获取非空OTPCode的解决方案
原代码的问题
- 异步时序错误:
cy.get('otpinput').type(otpValue)会在loopFunc中的API请求完成前执行,此时otpValue仍是初始空字符串,根本拿不到有效OTP。 - 递归未纳入Cypress命令队列:直接递归调用
loopFunc()没有通过Cypress的异步命令队列管理,可能导致执行顺序混乱,无法正确重复发起请求。 - 无终止条件:没有设置最大重试次数,若API一直返回空OTP,会陷入无限循环。
修复后的实现方案
方案1:带重试限制与等待的递归调用
let otpValue = ''; const MAX_RETRY = 10; // 限制最大重试次数,避免无限循环 let retryCount = 0; const fetchValidOTP = () => { cy.request({ method: 'GET', url: 'http://tesurl/api/otp/getotp', }).then((res) => { expect(res.status).to.equal(200); retryCount++; if (res.body.OTPCode) { // 获取到有效OTP,赋值后结束循环 otpValue = res.body.OTPCode; } else if (retryCount > MAX_RETRY) { // 超过重试次数,抛出错误终止 throw new Error(`已重试${MAX_RETRY}次,仍未获取到有效OTPCode`); } else { // 未获取到OTP,等待1秒后重试 cy.wait(1000); fetchValidOTP(); } }); }; // 确保在获取到OTP后再执行输入操作 fetchValidOTP().then(() => { cy.get('otpinput').type(otpValue); });
方案2:基于Promise的链式递归(更符合Cypress异步风格)
const getValidOTP = (retryCount = 0, maxRetry = 10) => { return cy.request('http://tesurl/api/otp/getotp').then((res) => { expect(res.status).to.equal(200); if (res.body.OTPCode) { return res.body.OTPCode; // 返回有效OTP,终止递归 } if (retryCount >= maxRetry) { throw new Error(`重试${maxRetry}次失败,未获取到OTPCode`); } // 等待1秒后递归调用,继续尝试 cy.wait(1000); return getValidOTP(retryCount + 1, maxRetry); }); }; // 链式调用获取OTP并输入 getValidOTP().then((otp) => { cy.get('otpinput').type(otp); });
关键说明
- 时序控制:通过
.then()链式调用,确保输入操作仅在成功获取OTP后执行,避免异步时序问题。 - 请求频率控制:加入
cy.wait(1000)避免短时间内频繁请求API,减轻服务器压力。 - 容错机制:设置最大重试次数,防止因API异常导致的无限循环。
内容的提问来源于stack exchange,提问作者imjayabal
相关产品推荐
相关产品推荐

