我正在使用Cypress。我有一个小的React应用程序和一个Flask后端。我希望我的测试能够调用后端以设置其将要运行的状态。我使用提取。这很好。赛普拉斯很生气,并且认为测试没有成功。我不是真正的javascript开发人员,所以这也许很明显,但是我不知道如何使它变得快乐。
这是我的测试代码:
it.only("edits a job", async () => {
const now = new Date().getTime()
const title = `Edit-This-${now}`
const newTitle = `SUCCESS-EDIT-${now}`
const company = `Edit Company-${now}`
const link = `https://example.com/edit-me-${now}`
const status = "Edit Test"
const body = JSON.stringify({company, title, link, status})
await fetch('/add_job', {method: 'post', headers: {'Content-Type': 'application/json'}, body: body})
cy.visit("http://localhost:3000/jobs_list")
cy.contains(title)
cy.contains(company)
cy.contains(link)
cy.contains(status)
cy.get(`[name=edit-${title}`).click()
cy.get(`[value=${title}`).clear().type(newTitle)
cy.get(`[name=save-${newTitle}`).click()
cy.contains(newTitle)
console.log("what the heck")
})
这似乎很好。但最后有一个CypressError:
Cypress command timeout of 4530ms exceeded. (and Mocha's done() called multiple times)
我还尝试了不使用async / await并在获取后将步骤放在then
中,但这没有帮助。将done
传递到it块并在结尾处调用done()
使其无法运行。这是有道理的,因为柏树的各个步骤看起来是同步的,但实际上却不是同步的,因此在执行任何步骤之前,它会先击中done()
。
使传递给it
的函数不异步并将获取更改为
cy.request('POST', 'http://localhost:3000/add_job', {'Content-Type': 'application/json', company, title, link, status})
代替fetch
似乎有效,但我想了解原因。
答案 0 :(得分:0)
https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Chains-of-Commands
了解赛普拉斯将命令链接在一起的机制非常重要。 它代表您管理一个Promise链,每个命令对下一个命令产生一个“主题”,直到链结束或遇到错误为止。 开发人员无需直接使用Promises,但了解它们的工作方式会有所帮助!
您可以通过Cypress.Promise
将项目添加到赛普拉斯的承诺链/队列中。您可以使用Cypress.Promise来封装fetch
呼叫,但是建议使用cy.request
,除非您出于某些特殊原因不使用它。
// wrap null, so that you can use `then` to invoke a callback as an arbitrary command
// and return a Cypress.Promise - so that cypress will wait on it's result
// (or just use cy.request :))
cy.wrap(null).then(() => {
return new Cypress.Promise((resolve, reject) => {
try {
fetch(/*...*/).then(resolve);
} catch (e) {
reject(e);
}
})
})
答案 1 :(得分:0)
使用 cy.request
而不是 fetch
。
https://docs.cypress.io/api/commands/request
cy.request({yourUri}).as("response"); // This takes care of the async task.
cy.get("@response").should((response) => {
// Carry on with the rest of your test
cy.get("some selector");
});