Cypress中使用this.*访问别名失效问题及原因咨询
Cypress别名通过
this访问的行为差异解析 问题场景
在尝试通过this访问Cypress别名时,出现以下矛盾现象:
- 在
cy.fixture().then()回调中,dataExample参数能正常获取fixture数据,但this.example为undefined - 回调外直接访问
this.example同样是undefined - 但将
cy.fixture().as()代码移至beforeEach()中时,this.example就能正常访问
问题代码示例
describe('cy.as and this', function () { it('Testing cy.as and this', function () { cy.fixture('example.json').as('example') .then(function (dataExample) { cy.log('ACCESSING this, dataExample', this, dataExample); }); cy.log(`ACCESSING this.example : ${JSON.stringify(this['example'])}`, this); }); });
正常运行的代码示例
describe('alias', () => { beforeEach(() => { cy.fixture('example.json').as('example'); }); it('can access all aliases as properties', function () { expect(this['example']).not.to.eq(undefined); // 断言成立 cy.log('THIS', this); // 输出显示example为undefined,但实际能访问到 cy.log('THIS.example', this['example']); // 正常输出fixture数据 }); });
原因解释
1. Cypress命令的异步执行特性
Cypress所有命令都是异步的,会被加入命令队列等待执行。问题代码中,cy.log(ACCESSING this.example...)是同步代码,会在cy.fixture()命令执行完成前就运行,此时别名还未挂载到this上,所以拿到的是undefined。
2. 别名挂载到this的时机
使用.as()创建别名时,Cypress不会立即将别名挂载到测试上下文this上,而是会等待当前命令队列全部执行完成后,才完成挂载动作。
- 在问题代码的
then回调中,虽然fixture数据已经加载完成,但整个命令队列(包括cy.fixture().as().then())还在执行中,挂载动作尚未触发,所以this.example还是undefined。
3. beforeEach()的执行时机
beforeEach()会在每个it块执行之前就完成所有内部命令队列的执行。当进入it块时,cy.fixture().as()已经执行完毕,别名也已经挂载到this上,因此能正常访问this.example。
4. 关于cy.log('THIS', this)的特殊现象
在正常运行的代码中,cy.log('THIS', this)显示example为undefined,但cy.log('THIS.example', this['example'])却能拿到数据,原因是:
cy.log是异步命令,第一个cy.log执行时,Cypress可能还未完成别名挂载;而第二个cy.log执行时,挂载动作已经完成。- 直接同步打印
this时,是在it块刚进入的同步阶段,此时别名还未挂载,但异步命令执行时,上下文已经更新。
5. 函数类型的注意点
必须使用普通function定义it块,不能用箭头函数——箭头函数的this会指向外层上下文,无法访问Cypress的测试上下文对象,也就拿不到别名数据。
内容的提问来源于stack exchange,提问作者Gauthier Peel
相关产品推荐
相关产品推荐

