在执行测试之前等待自己的函数(returns 一个承诺)
Wait for an own function (which returns a promise) before tests are executed
我是 cypress 的新手,正在尝试弄清楚它是如何工作的。
我有自己的功能(调用测试控制器服务器来重置数据库)。它 returns 一个在数据库成功重置后完成的承诺。
function resetDatabase(){
// returns a promise for my REST api call.
}
我的目标是能够在所有测试之前执行它。
describe('Account test suite', function () {
// how can I call resetDb here and wait for the result
// before the tests below are invoked?
it('can log in', function () {
cy.visit(Cypress.config().testServerUrl + '/Account/Login/')
cy.get('[name="UserName"]').type("admin");
cy.get('[name="Password"]').type("123456");
cy.get('#login-button').click();
});
// .. and more test
})
我如何在 cypress 中做到这一点?
更新
我试过了
before(() => {
return resetDb(Cypress.config().apiServerUrl);
});
但随后我收到一条警告:
Cypress detected that you returned a promise in a test, but also invoked one or more cy commands inside of that promise
我不会在 resetDb()
中调用 cy
。
Cypress 有 promises(Cypress.Promise), but they are not real promises, more like duck typing。事实上,Cypress 并不是 100% 兼容真正的 promises,它们可能有效,也可能无效。
将 Cypress.Promise
视为任务或操作。它们与所有其他赛普拉斯命令顺序执行。
要让您的函数进入 Cypress 管道,您可以使用 custom commands。文档没有说明,但您可以从他们那里 return Cypress.Promise
。
Cypress.Commands.add('resetDb', function () {
var apiServerUrl = Cypress.config().apiServerUrl;
return new Cypress.Promise((resolve, reject) => {
httpRequest('PUT', apiServerUrl + "/api/test/reset/")
.then(function (data) {
resolve();
})
.catch(function (err) {
reject(err);
});
});
});
然后可以从测试本身执行该命令,或者像我的情况一样从 before()
.
describe('Account', function () {
before(() => {
cy.resetDb();
});
it('can login', function () {
// test code
});
})
您可以使用 cy.wrap( promise )
,尽管它 never times out 可能仍然存在错误(尚未测试)。
否则,您可以使用 cy.then()
(未记录,将来可能会中断,我肯定不会通过推广内部 API 来做任何事情):
cy.then(() => {
return myAsyncFunction();
});
您可以在规范的顶层使用这两个命令,就像您使用任何命令一样,它会被排入 cypress 命令队列并按顺序执行。
但与cy.wrap
(IIRC) 不同,cy.then()
支持传递回调,这意味着您可以在 cy 的时间 执行您的异步函数 命令正在执行,而不是在规范的开头(因为传递给 cy 命令的表达式会立即求值)---这就是我在上面的示例中所做的。
我是 cypress 的新手,正在尝试弄清楚它是如何工作的。
我有自己的功能(调用测试控制器服务器来重置数据库)。它 returns 一个在数据库成功重置后完成的承诺。
function resetDatabase(){
// returns a promise for my REST api call.
}
我的目标是能够在所有测试之前执行它。
describe('Account test suite', function () {
// how can I call resetDb here and wait for the result
// before the tests below are invoked?
it('can log in', function () {
cy.visit(Cypress.config().testServerUrl + '/Account/Login/')
cy.get('[name="UserName"]').type("admin");
cy.get('[name="Password"]').type("123456");
cy.get('#login-button').click();
});
// .. and more test
})
我如何在 cypress 中做到这一点?
更新
我试过了
before(() => {
return resetDb(Cypress.config().apiServerUrl);
});
但随后我收到一条警告:
Cypress detected that you returned a promise in a test, but also invoked one or more cy commands inside of that promise
我不会在 resetDb()
中调用 cy
。
Cypress 有 promises(Cypress.Promise), but they are not real promises, more like duck typing。事实上,Cypress 并不是 100% 兼容真正的 promises,它们可能有效,也可能无效。
将 Cypress.Promise
视为任务或操作。它们与所有其他赛普拉斯命令顺序执行。
要让您的函数进入 Cypress 管道,您可以使用 custom commands。文档没有说明,但您可以从他们那里 return Cypress.Promise
。
Cypress.Commands.add('resetDb', function () {
var apiServerUrl = Cypress.config().apiServerUrl;
return new Cypress.Promise((resolve, reject) => {
httpRequest('PUT', apiServerUrl + "/api/test/reset/")
.then(function (data) {
resolve();
})
.catch(function (err) {
reject(err);
});
});
});
然后可以从测试本身执行该命令,或者像我的情况一样从 before()
.
describe('Account', function () {
before(() => {
cy.resetDb();
});
it('can login', function () {
// test code
});
})
您可以使用 cy.wrap( promise )
,尽管它 never times out 可能仍然存在错误(尚未测试)。
否则,您可以使用 cy.then()
(未记录,将来可能会中断,我肯定不会通过推广内部 API 来做任何事情):
cy.then(() => {
return myAsyncFunction();
});
您可以在规范的顶层使用这两个命令,就像您使用任何命令一样,它会被排入 cypress 命令队列并按顺序执行。
但与cy.wrap
(IIRC) 不同,cy.then()
支持传递回调,这意味着您可以在 cy 的时间 执行您的异步函数 命令正在执行,而不是在规范的开头(因为传递给 cy 命令的表达式会立即求值)---这就是我在上面的示例中所做的。