You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:12:34