如何在Cypress中设置初始时间并让时间自然流逝?
解决Cypress设置初始时间后让时间自然流逝的问题
默认情况下,cy.clock()会冻结时间,必须通过cy.tick()手动推进。要实现设置固定初始时间,同时让时间随真实测试时长自然流逝,你需要自定义mock Date对象,而非依赖cy.clock()的默认行为。
实现步骤
- 定义测试的基准初始时间(注意JS的月份是0-based,7月对应
6) - 记录测试启动时的真实时间,用于计算后续时间偏移量
- 重写页面的
Date构造函数和Date.now(),让它们返回基准时间加上真实流逝的时长
代码示例
// 在测试用例或before钩子中执行 const targetInitialTime = new Date(2023, 6, 3, 12, 0, 0).getTime(); // 2023年7月第一个周一12点 const testStartRealTime = Date.now(); cy.window().then(win => { const OriginalDate = win.Date; // 重写Date构造函数 win.Date = function(...args) { if (args.length === 0) { // 无参调用时,返回基准时间 + 真实流逝的时间 return new OriginalDate(targetInitialTime + (Date.now() - testStartRealTime)); } // 有参调用时保持原生行为(比如new Date('2023-01-01')) return new OriginalDate(...args); }; // 重写Date.now()方法 win.Date.now = () => targetInitialTime + (Date.now() - testStartRealTime); });
原理说明
- 这种方式通过计算真实时间流逝量,动态偏移基准初始时间,模拟出时间自然推进的效果
- 保留了
Date的原生有参构造行为,不会影响代码中对特定日期的创建 - 不需要手动调用
cy.tick(),测试过程中时间会随真实等待时长自动更新
注意点
- JS的
Date月份是0索引(1月为0,12月为11),你之前代码里的new Date(2023,7,1)实际指向8月1日,需要修正为2023,6,x来指定7月的日期 - 如果同时需要mock定时器(
setTimeout/setInterval),可以结合cy.clock()但不传入['Date']参数,避免和自定义的Datemock冲突
内容的提问来源于stack exchange,提问作者Rafał G.
相关产品推荐
相关产品推荐

