【问题标题】:Chaining functions in CypressCypress 中的链接函数
【发布时间】:2021-01-23 13:32:03
【问题描述】:

上下文

我很难理解 Cypress 中的异步何时应该由开发人员处理,什么时候不应该由开发人员处理(因为它是在后台处理的)。

考虑这两个测试:

一)

it('stackoverflow example',() => {
    cy.get('#soSection').should('contain', 'Stack Overflow').then(() =>{
      cy.get('#soButton').click().then(() => {
        cy.get('#soSection').should('not.contain', 'Stack Overflow');
      });
    });
});

B)

it('stackoverflow example',() => {
  cy.get('#soSection').should('contain', 'Stack Overflow');
  cy.get('#soButton').click();
  cy.get('#soSection').should('not.contain', 'Stack Overflow');
});
  • #soSection 将包含“堆栈溢出”,直到我们单击该按钮。因此,两条线路应该以某种方式同步运行。
  • (A) 使用then使您能够处理从上一个命令产生的主题。 (B) 不使用它。

到目前为止我已经尝试过什么

我已运行 (A) 和 (B) 测试。两种方法都运行良好且行为方式相同。


怀疑

  1. 如果我们需要使用前面的主题,那么我们应该只使用方法 (A) 和可链接的对象。在其他情况下,我们必须像 (A) 示例中那样使用可链式吗?
  2. 查看(B)中的3行代码。我们希望这 3 行按此顺序运行以取得成功。但是,赛普拉斯声称异步运行。因此,我们如何确定这 3 行代码会按照预期的顺序运行?

【问题讨论】:

    标签: javascript testing cypress


    【解决方案1】:

    您应该阅读名为Introduction to Cypress from the Official documentation 的页面,或者更一般地说,阅读“核心概念”菜单下的所有内容。其中大部分主题和概念都在此处进行了解释。

    命令产生

    您的假设是正确的,如果您需要上一个主题,则需要使用then,因为赛普拉斯是异步的并且不返回主题。相反,它会产生它。这表示为core concept of subject management

    Cypress 命令不返回它们的主题,而是让它们。请记住:赛普拉斯命令是异步的,并且会排队等待稍后执行。在执行过程中,从一个命令到下一个命令会产生主题,并且在每个命令之间运行大量有用的赛普拉斯代码以确保一切正常。

    subject management section 显示了产生示例:

    有些方法产生null,因此不能被链接,例如cy.clearCookies()

    某些方法,例如 cy.get()cy.contains(),会产生一个 DOM 元素,允许将进一步的命令链接到它们(假设它们需要一个 DOM 主题),例如 .click() 甚至 cy.contains()

    每个命令产生不同的东西。您可以在每个命令的文档中检查这一点。例如,cy.children's yield section 声明它返回一个 DOM 元素。

    从技术上讲,您甚至不需要在每个命令之前添加cy.,因为它们都返回cy,从而使每个命令都可以链接。通常您只需要在命令链的开头使用.cy(就像在then 块内的开头一样)。这更像是一个代码风格问题。

    命令执行

    当您运行 3 cy.get 行时,命令本身不会被执行,它们只会被赛普拉斯添加到队列中。赛普拉斯将跟踪您的命令并按顺序运行它们。每个命令都有一个超时时间,并会等待在该时间范围内满足命令条件。

    正如Commands Are Asynchronous 部分所述:

    Cypress 命令在调用它们的那一刻不做任何事情,而是将它们自己排入队列以便稍后运行。这就是我们所说的赛普拉斯命令是异步的。

    从技术上讲,我应该引用文档的整个页面,因为它的结构非常好,简洁且详细,包含大量示例代码。我强烈推荐阅读它。

    总结

    简而言之,通过cy. 调用,您可以排队为赛普拉斯运行命令。如果您需要运行自己的同步代码,或者需要生成的主题,您应该在想要运行该代码的赛普拉斯命令之后添加.then()。您可以在.then() 中编写所有连续命令,但这是不必要的,您只需重新创建 JS then 厄运圣诞树 AKA callback hell。因此,如果您需要上一个命令的 yield 主题或想要注入同步代码,请仅使用 then。当然,在一些同步代码(如if 条件)之后,您需要再次调用cy.,它们将在then 中排队。是否将剩余的cy. 命令添加到then 或以上一层或多层,取决于您是否需要处理给定then 块内发生的内容,或者您​​喜欢如何设置代码样式。这是为演示而修改的文档中的一个示例:

    it('test', () => {
      cy.visit('https://app.com')
      // these lines will be queued up and will be run by Cypress in order
      cy.get('ul>li').eq(4)
      cy.get('.nav').contains('About')
      // we want to use the .user field's value
      cy.get('.user')
        .then(($el) => {
          // this line evaluates after the .then() executes
          let username = $el.text()
          // synchronous code to decide which commands to run (queue up)
          if (username) {
            // "queue up" other commands
            cy.contains(username).click()
            cy.get('ul>li').eq(2)
          } else {
            cy.get('My Profile').click()
          }
        })
      // command that doesn't depend on data inside the `then` block
      cy.get('.status').contains('Done')
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2021-09-15
      • 1970-01-01
      • 2022-11-25
      相关资源
      最近更新 更多