【问题标题】:In my Cypress.io tests why do I need to treat a cy.task like it is asyncronous when its not在我的 Cypress.io 测试中,为什么我需要将 cy.task 视为异步的而不是异步的
【发布时间】:2025-12-20 16:35:11
【问题描述】:

我有Cypress.io 测试使用简单的Cypress task 将一些表信息记录到终端。例如我有一个这样的测试:

it("Writes some console logs and checks a val", () => {
  cy.task("rowLog", { id: 1, name: "foo", type: "bar" });
  let one = 1;
  expect(one).to.equal(2);
});

任务,“rowLog”是这样的:

module.exports = (on, config) => {
  on("task", {
  rowLog(data) {
    // use node.js console.table to pretty print table data:
    console.table(data);
    return null;
  },
}

但是如果我通过Cypress run 无头运行赛普拉斯,rowLog 的结果将不会显示在我的终端中。这是因为测试会失败。如果我们切换测试让它通过,那么它就会显示出来。

但是我刚刚意识到,如果我将rowLog 视为如下所示的异步。它将结果打印到终端:

it("Writes some console logs and checks a val", () => {
  // add a .then to task:
  cy.task("rowLog", { id: 1, name: "foo", type: "bar" }).then(() => {
    let one = 1;
    expect(one).to.equal(2);
  });
});

这不是我对文档的期望。他们说:

cy.task() 产生由 pluginsFile 中的任务事件返回或解析的值。 (source)

并且一项任务可以产生一个承诺或一个价值

我是赛普拉斯的新手——我有什么遗漏或做错了吗?我希望能够不必将我的任务与.then 语句链接起来,如果它只是同步的东西,比如编写输出以确保所有内容都发送到我的终端。

【问题讨论】:

    标签: cypress


    【解决方案1】:

    如果您查看cy.task 命令的类型定义,您会看到它返回一个可链接的(即类似promise 的实体)。所以它的行为就像任何其他 cy 命令(异步)。 至于yield either a promise or a **value** - 此语句指的是任务的处理程序,而不是任务本身。至于其他命令,如果处理程序没有完成,Cypress 会将返回值包装到 Promise 中。

    【讨论】:

    • 谢谢,所以如果我想获得我的 cy.task 的结果,我必须将随后的所有内容都包装在 .then 语句中吗?如果我想多次运行这个任务怎么办。如何避免链接一大堆 .then 语句?有更好的方法吗?
    • 是的,要处理cy.task 的结果,您必须使用同步代码块(thenshould)。与其他 cy 命令一样,您可以多次调用cy.task,Cypress 将按相同顺序执行较晚的任务。因此,如果您只想调用任务而不处理结果,则不需要回调链。