如何为Cypress中的resWait函数添加2分钟超时并关联Promise?
解决方案:为resWait添加超时控制并结合Promise
问题分析
你之前的尝试无效,原因在于:
- 外部
setTimeout(resWait, 20000)仅延迟调用resWait,但函数内部的递归会持续执行,没有终止机制 - Cypress命令基于异步队列,普通
setTimeout无法中断Cypress的递归调用流程
改造步骤
1. 将resWait封装为返回Promise的函数
把递归检查逻辑包装到Promise中,成功时resolve,失败时reject,同时用你的sleepPromise替代cy.wait,让递归逻辑基于Promise链:
function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function resWait() { return new Promise((resolve, reject) => { const checkTransactionStatus = () => { cy.req( 'GET', `${url}/transaction/acquirertrxquery?acquirerId=1&dateFrom=${actualDate}%2000:00:00&dateTo=${actualDate}%2023:59:00&externalId=${idExternal}` ).then((res) => { // 处理content为空的边界情况,避免报错 const status = res.body.content[0]?.trxConfirmationStatus?.description; if (status === 'Confirmed') { resolve('交易已确认'); return; } // 等待3秒后递归检查 sleep(3000).then(checkTransactionStatus); }).catch(err => { // 请求失败时触发reject reject(new Error('查询交易状态失败:' + err.message)); }); }; // 启动首次检查 checkTransactionStatus(); }); }
2. 添加2分钟超时控制
使用Promise.race让resWait和超时Promise竞争,无论哪个先完成,都进入后续测试流程:
// 定义2分钟(120000毫秒)的超时Promise const timeoutPromise = new Promise(resolve => { setTimeout(() => { resolve('超时:已达到2分钟上限,进入后续测试'); }, 120000); }); // 同时执行状态检查和超时逻辑 Promise.race([resWait(), timeoutPromise]) .then(result => { // 成功确认或超时都执行后续测试 cy.log(result); // 这里写入你的后续测试流程代码 // 例如:cy.visit('/next-test-page') }) .catch(err => { // 处理请求错误的情况,也可选择进入后续流程 cy.log(err.message); // 后续测试流程 });
关键说明
Promise.race会优先执行先完成的Promise,超时后会直接终止等待状态检查的逻辑- 用
sleepPromise替代cy.wait,让递归逻辑处于Promise链中,才能被Promise.race正确中断 - 添加了可选链
?.处理res.body.content[0]为空的情况,避免因接口返回异常导致测试崩溃
内容的提问来源于stack exchange,提问作者EFPM_S
相关产品推荐
相关产品推荐

