如何确保cy.writeFile()在cy.intercept()执行前完成?
解决Cypress中fixture更新后再执行cy.intercept的问题
你的问题核心是cy.intercept使用{fixture: 路径}配置时,会在调用intercept的瞬间就读取文件内容,而非实际请求触发时再读取。所以即便后续通过cy.writeFile更新了文件,拦截逻辑已经提前使用了旧的fixture内容。
下面给出两种可靠的解决方案:
方案一:直接使用内存中的更新后数据(推荐)
跳过文件写入/读取的异步依赖,直接将更新后的内存数据作为intercept响应体,彻底避免文件系统的时序问题:
describe('NBA pregame EventTile verification', () => { beforeEach('Enforce game start time', function () { // 修改updateSchedule,返回更新后的数据集 const updateSchedule = (filePath, updateCallback) => { return cy.fixture(filePath).then((nbaData) => { updateCallback(nbaData); // 可选:写入文件保留修改 + 返回内存中的更新后数据 return cy.writeFile(filePath, nbaData).then(() => nbaData); }); }; // Update QB schedule and set up interception const updateQBAndIntercept = () => { return updateSchedule('Odds/QB/NBA1Schedule.json', (nbaData) => { const nbaGame = nbaData.NBA[0]; const currentTimestamp = Date.now(); const adjustedStartTime = currentTimestamp + (2 * 60 * 60 * 1000); // 2小时后 nbaGame.startTime = adjustedStartTime; }).then((updatedQBData) => { // 直接用内存数据作为响应,不再读取文件 return cy.intercept('GET', '**/quarterback/lighterGames/leagues/**', updatedQBData).as('nbaPregameqb'); }); }; // Update DK schedule and set up interception const updateDKAndIntercept = () => { return updateSchedule('Odds/DK/NBA1Schedule.json', (nbaData) => { const nbaGame = nbaData.NBA[0]; const currentDate = new Date(); const adjustedStartDate = new Date(currentDate.getTime() + (2 * 60 * 60 * 1000)); // 2小时后 nbaGame.startDate = adjustedStartDate.toISOString(); }).then((updatedDKData) => { return cy.intercept('GET', '**/sports-oddsapp-offers.xreapps.net/dk/events/**', updatedDKData).as('nbaPregamedk'); }); }; // 无需动态更新的intercept保持原配置 cy.intercept('GET', '**/quarterback/lighterGame/league/**', { fixture: 'Odds/QB/NBA1Details.json' }).as('nbaPregameDetailqb'); cy.intercept('GET', '**/sports-oddsapp-offers.xreapps.net/dk/props,lines/**', { fixture: 'Odds/DK/NBA1Details.json' }).as('nbaPregameDetaildk'); const launchAppAndWaitForIntercepts = () => { cy.launchOddsApp(); return cy.wait(['@nbaPregameqb', '@nbaPregamedk']); }; // 链式调用保持不变 updateQBAndIntercept() .then(updateDKAndIntercept) .then(launchAppAndWaitForIntercepts); }) context('Odds Explorer Page', () => { it.only('Should have NBA pregame Tile', () => { // 你的测试逻辑 }) }) })
方案二:在intercept中动态读取最新文件(需依赖文件场景)
如果必须通过修改后的fixture文件响应请求,可在intercept的handler函数中用cy.readFile读取最新内容,确保请求触发时拿到的是更新后的数据:
// 修改updateQBAndIntercept逻辑示例 const updateQBAndIntercept = () => { // 先完成文件更新 return updateSchedule('Odds/QB/NBA1Schedule.json', (nbaData) => { const nbaGame = nbaData.NBA[0]; const currentTimestamp = Date.now(); const adjustedStartTime = currentTimestamp + (2 * 60 * 60 * 1000); nbaGame.startTime = adjustedStartTime; }).then(() => { // 请求触发时读取最新文件 return cy.intercept('GET', '**/quarterback/lighterGames/leagues/**', (req) => { return cy.readFile('cypress/fixtures/Odds/QB/NBA1Schedule.json').then(data => { req.reply(data); }); }).as('nbaPregameqb'); }); };
注意:这里需要填写完整的fixture文件相对路径(相对于项目根目录),避免路径解析错误。
两种方案对比:
- 方案一性能更优,无额外文件IO操作,时序完全可控;
- 方案二适合需要保留修改后fixture文件,供后续测试复用的场景。
内容的提问来源于stack exchange,提问作者Kakali Mahapatra
相关产品推荐
相关产品推荐

