赛普拉斯测试之间通过状态的最佳实践是什么
What is the best practice of pass states between tests in Cypress
我想 pass/share 每次测试之间的数据。在 Cypress 中实现它的最佳方法是什么?
例如:
it('test 1'), () => {
cy.wrap('one').as('a')
const state1 = 'stat1'
})
it('test 2'), () => {
cy.wrap('two').as('b')
})
it('test 2'), () => {
//I want to access this.a and this.b
//Also I want to access state1
})
在 Javascript 个变量的情况下,你可以这样做:
let state;
describe('test 1', () => {
it('changes state', () => {
state = "hi";
});
});
describe('test 2', () => {
it('reports state', () => {
cy.log(state); // logs "hi" to the Cypress log panel
});
});
.as()
似乎无法在 describe
块之间携带状态。
假设您正在尝试传递文本
it('test 1'), () => {
cy.wrap('one').as('a')
}
it('test 2'), () => {
cy.wrap({ valueName: 'two' }).as('b')
}
it('test 2'), () => {
//I want to access this.a and this.b
cy.get('@a').then((thisIsA) => {
cy.log(thisIsA);
// logs 'one'
}
cy.get('@b').its('valueName').then((thisIsB) => {
cy.log(thisIsB);
// logs 'two'
}
cy.get('@b').its('valueName').should('eq', 'two')
}
我尝试了其他一些解决方案,但它们对我不起作用。也许最近的版本发生了变化。以下示例应该有效。请注意两个测试都使用了 function() ,这使事情保持在 'this.'.
的上下文中
it('get the value', function () {
cy.get('#MyElement').invoke('text').as('mytext1')
})
it('use the value', function () {
cy.log(this.mytext1);
})
正如 abbr
在评论中指出的那样,如果测试在不同的 url.
上开始,则使用全局变量共享值将不起作用
所以这些不起作用:
- 全局变量赋值和读取(是否在
describe
/context
块外无关紧要)
- 依赖
Mocha
this.state
(这个测试完就清零了)
- 使用
Cypress
as
describe("Test", () => {
it("Can access 3000", function () {
cy.visit("http://localhost:3000");
cy.writeFile("shared.json", {count: 2})
});
it("Can access 8000", function () {
cy.visit("http://localhost:8000");
cy.readFile("shared.json").then(cy.log)
});
});
您可以像这样在步骤之间共享状态
describe('A suite of steps', () => {
it('visit a page and save the url', function () {
cy.visit('/hello-world')
// Store url
cy.url().as('pageUrl');
});
it('load page url', function () {
// Load the page from the previous step
cy.visit(this.pageUrl)
});
})
我可以看到作者的答案有效,但如果有人需要在不同的测试文件之间共享数据,解决方案是使用 cy task method 并将数据存储在 Node 环境中,例如在我的例子中,我需要存储用户数据:
// cypress/plugins/index.ts
export default (on, config) => {
on('task', {
setUserData: (userData: UserDataType) => {
global.userData = userData;
return null;
},
getUserData: () => {
return global.userData;
},
});
};
然后在测试用例中我们可以这样做:
// cypress/integration/login.spec.ts
describe('Login', () => {
it('should work', () => {
cy.visit('/login-page');
cy.intercept('api/login-endpoint').as('postLogin');
// login interactions
cy.wait('@postLogin').then((interception) => {
// intercept user data and store it in global variable
cy.task('setUserData', JSON.parse(interception.response.body));
});
// ... further assertions
});
});
稍后我们可以轻松检索此数据:
// cypress/integration/otherTest.spec.ts
describe('Other test', () => {
it('uses user data', () => {
cy.task('getUserData').then((userData: UserDataType) => {
console.log(userData);
// voila! Stored data between two .spec files
});
});
});
您还需要为此扩展 Node TS 类型,但这个答案已经足够长了。
是的,我知道这根本不是编写测试的好方法,因为它使它们相互依赖,但有时应用程序中的长时间交互流程使它成为必要。
在处理这个问题时,我无意中找到了解决方案。不知道为什么会这样。导入任何 json 文件(此解决方案不会更改 json 文件)
someTest.spec.js:
import jsonFile from "../../fixtures/file.json"
describe('Test some feature', () =>{
it('test feature 1', () => {
jsonFile.anyWalueYouWant="this is value from feature 1"
})
it("test feature 2", ()=>{
cy.log(jsonFile.anyWalueYouWant)
})
})
PS:anyWalueYouWant 不需要在这个 parameters.json 文件中
我想 pass/share 每次测试之间的数据。在 Cypress 中实现它的最佳方法是什么?
例如:
it('test 1'), () => {
cy.wrap('one').as('a')
const state1 = 'stat1'
})
it('test 2'), () => {
cy.wrap('two').as('b')
})
it('test 2'), () => {
//I want to access this.a and this.b
//Also I want to access state1
})
在 Javascript 个变量的情况下,你可以这样做:
let state;
describe('test 1', () => {
it('changes state', () => {
state = "hi";
});
});
describe('test 2', () => {
it('reports state', () => {
cy.log(state); // logs "hi" to the Cypress log panel
});
});
.as()
似乎无法在 describe
块之间携带状态。
假设您正在尝试传递文本
it('test 1'), () => {
cy.wrap('one').as('a')
}
it('test 2'), () => {
cy.wrap({ valueName: 'two' }).as('b')
}
it('test 2'), () => {
//I want to access this.a and this.b
cy.get('@a').then((thisIsA) => {
cy.log(thisIsA);
// logs 'one'
}
cy.get('@b').its('valueName').then((thisIsB) => {
cy.log(thisIsB);
// logs 'two'
}
cy.get('@b').its('valueName').should('eq', 'two')
}
我尝试了其他一些解决方案,但它们对我不起作用。也许最近的版本发生了变化。以下示例应该有效。请注意两个测试都使用了 function() ,这使事情保持在 'this.'.
的上下文中 it('get the value', function () {
cy.get('#MyElement').invoke('text').as('mytext1')
})
it('use the value', function () {
cy.log(this.mytext1);
})
正如 abbr
在评论中指出的那样,如果测试在不同的 url.
所以这些不起作用:
- 全局变量赋值和读取(是否在
describe
/context
块外无关紧要) - 依赖
Mocha
this.state
(这个测试完就清零了) - 使用
Cypress
as
describe("Test", () => {
it("Can access 3000", function () {
cy.visit("http://localhost:3000");
cy.writeFile("shared.json", {count: 2})
});
it("Can access 8000", function () {
cy.visit("http://localhost:8000");
cy.readFile("shared.json").then(cy.log)
});
});
您可以像这样在步骤之间共享状态
describe('A suite of steps', () => {
it('visit a page and save the url', function () {
cy.visit('/hello-world')
// Store url
cy.url().as('pageUrl');
});
it('load page url', function () {
// Load the page from the previous step
cy.visit(this.pageUrl)
});
})
我可以看到作者的答案有效,但如果有人需要在不同的测试文件之间共享数据,解决方案是使用 cy task method 并将数据存储在 Node 环境中,例如在我的例子中,我需要存储用户数据:
// cypress/plugins/index.ts
export default (on, config) => {
on('task', {
setUserData: (userData: UserDataType) => {
global.userData = userData;
return null;
},
getUserData: () => {
return global.userData;
},
});
};
然后在测试用例中我们可以这样做:
// cypress/integration/login.spec.ts
describe('Login', () => {
it('should work', () => {
cy.visit('/login-page');
cy.intercept('api/login-endpoint').as('postLogin');
// login interactions
cy.wait('@postLogin').then((interception) => {
// intercept user data and store it in global variable
cy.task('setUserData', JSON.parse(interception.response.body));
});
// ... further assertions
});
});
稍后我们可以轻松检索此数据:
// cypress/integration/otherTest.spec.ts
describe('Other test', () => {
it('uses user data', () => {
cy.task('getUserData').then((userData: UserDataType) => {
console.log(userData);
// voila! Stored data between two .spec files
});
});
});
您还需要为此扩展 Node TS 类型,但这个答案已经足够长了。
是的,我知道这根本不是编写测试的好方法,因为它使它们相互依赖,但有时应用程序中的长时间交互流程使它成为必要。
在处理这个问题时,我无意中找到了解决方案。不知道为什么会这样。导入任何 json 文件(此解决方案不会更改 json 文件)
someTest.spec.js:
import jsonFile from "../../fixtures/file.json"
describe('Test some feature', () =>{
it('test feature 1', () => {
jsonFile.anyWalueYouWant="this is value from feature 1"
})
it("test feature 2", ()=>{
cy.log(jsonFile.anyWalueYouWant)
})
})
PS:anyWalueYouWant 不需要在这个 parameters.json 文件中