为何赋值运算符先于声明的Action执行?Cypress执行顺序疑问
问题原因分析
这不是Cypress的性能优化导致的,核心原因是Cypress的命令异步队列机制:
- 所有
cy.xxx()类型的命令(比如cy.xpath().click())不会立即执行,而是被加入到Cypress的命令队列中,等待之前的命令执行完成后再依次执行。 - 而
then回调里的同步代码(比如someGlobalVariable = 'some value'、console.log)会在回调被触发时立即同步执行,不会等待队列里的cy命令完成。
所以你的代码里,action1()完成后触发then回调,此时同步代码先执行,而action2的cy命令只是被加入队列还没实际执行,就出现了全局变量先被初始化的情况。
修复方案
要让全局变量赋值在action2执行完成后再进行,必须把赋值操作放到action2的命令链后面,或者用then衔接:
方案1:将赋值操作加入命令链
把同步代码放到action2的.then()回调里,确保在action2执行完成后再执行:
let someGlobalVariable = undefined; describe('Test description', () => { it('Should init global variable after action 2', () => { action1() // returns Chainable object .then(() => { // 执行action2,返回Chainable return cy.xpath('myXpath').click(); }) .then(() => { someGlobalVariable = 'some value'; console.log('someGlobalVariable initialized'); }); }); })
方案2:在action2内部用.then衔接
如果action2是多个命令,也可以在每个cy命令后用then确保顺序:
let someGlobalVariable = undefined; describe('Test description', () => { it('Should init global variable after action 2', () => { action1() .then(() => { cy.xpath('myXpath').click().then(() => { someGlobalVariable = 'some value'; console.log('someGlobalVariable initialized'); }); }); }); })
方案3:使用Cypress的wrap命令包裹同步代码(可选)
如果需要把同步代码也加入命令队列,确保执行顺序,可以用cy.wrap():
let someGlobalVariable = undefined; describe('Test description', () => { it('Should init global variable after action 2', () => { action1() .then(() => { cy.xpath('myXpath').click() cy.wrap(null).then(() => { someGlobalVariable = 'some value'; console.log('someGlobalVariable initialized'); }); }); }); })
注意事项
- 不要在Cypress测试中过度依赖全局变量,优先使用Cypress的
cy.wrap()、测试上下文(需把箭头函数改成普通函数)来传递数据,避免异步顺序问题。 - 所有需要依赖
cy命令执行结果的操作,都必须放到命令链的then回调中,不能直接写同步代码。
内容的提问来源于stack exchange,提问作者Anton Minchenko
相关产品推荐
相关产品推荐

