Cypress.io如何处理异步代码 [英] Cypress.io How to handle async code

查看:430
本文介绍了Cypress.io如何处理异步代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我们的应用程序正在采用SPA方式,因此我正处于将旧的水豚测试移至cypress.io的过程中.

I'm in the middle of process of moving our old capybara tests to cypress.io as our application is going SPA way.

在我们的案例中,我们有2000多项测试涵盖了许多功能. 因此,测试功能的常见模式是让用户拥有创建和发布的报价.

In our case we have over 2000 tests covering a lot of features. So common pattern to test feature is to have an user with created and published offer.

在开始的时候,我写了一个案例,其中柏树进入低谷页面并单击所有内容.它奏效了,但我看到要约创建和发布花费了将近1.5分钟才能完成.有时我们需要多个报价.因此,我们进行了5分钟的测试,还有1999年可以重写.

On the beginning I wrote case where cypress were going trough page and clicking everything. It worked but I saw that offer create + publish took almost 1,5 minute to finish. And sometimes we need multiple offers. So we have a test which takes 5 minutes and we have 1999 left to rewrite.

我们想出了REST API来创建商品和用户,这基本上是准备测试环境的捷径.

We came up with REST API to create offer and user, basically shortcut for test env preparation.

我发现使用async/await一切正常.所以这就是事情.如果我想在cypress上使用普通的异步JS代码,我会得到Error: Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

I came to the point where everything is working using async/await. So here's the thing. If I want to use normal async JS code with cypress I get Error: Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

这是它的样子:

    const faker = require('faker')
    import User from '../../support/User';

    describe('Toggle button for description offer', () => {
      const user = new User({
        first_name: faker.name.firstName(),
        last_name: faker.name.firstName(),
        email: `QA_${faker.internet.email()}`,
        password: 'xxx'
      })
      let offer = null

      before(async () => {
        await user.createOnServer()
        offer = await user.createOffer()
        await offer.publish()
      })

      beforeEach(() => {
        user.login()
        cy.visit(`/offers/${offer.details.id}`)
        cy.get('.offer-description__content button').as('showMoreButton')
      })

      it('XXX', function () {
        ...some test
      })
    })

此代码段按预期方式工作.首先,它会在之前触发并创建整个环境,然后在完成后进一步进行操作,然后再开始测试.

This snippet works as expected. Firstly it fires before and creates whole env then when it's done it goes further to beforeEach and starts testing.

现在我想合并之前和之前每个类似

Now I would like to merge before and beforeEach like

  before(async () => {
    await user.createOnServer()
    offer = await user.createOffer()
    await offer.publish()
    user.login()
    cy.visit(`/offers/${offer.details.id}`)
    cy.get('.offer-description__content button').as('showMoreButton')
  })

这将由于async关键字而失败. 现在的问题是:如何将其重写以一起使用async/await和cypress命令?我试图用普通的Promise重写它,但是它也行不通...

Which will fail because of async keyword. Now the question is: how to rewrite it to use async/await and cypress commands together? I tried to rewrite it with normal Promise but It won't work too ...

任何帮助表示赞赏.

推荐答案

您的问题源于

Your problem stems from the fact that cypress commands are not promises, although behaving like promises.

我可以想到两种选择:

  • Try to refactor your test code to not use async/await, as these commands don't behave as expected when running your code on cypress (check this bug). Cypress already has a whole way of dealing with async code as it creates a command queue that always run sequentially and in the expected order. That means you could observe the effects of your async code to validate that it happened before moving forward on your test. For instance, if User.createUserOnServer must wait a successful API call, add code to your test that will wait for the request to complete, using cy.server(), cy.route() and cy.wait(), like below:

cy.server();
cy.route('POST', '/users/').as('createUser');
// do something to trigger your request here, like user.createOnServer()
cy.wait('@createUser', { timeout: 10000});

  • 使用另一个第三方库来更改cypress与async/await的工作方式,例如柏树的承诺.此lib可以帮助您将cypress命令视为可以在before代码中await的承诺(有关更多信息,请参见

  • Use another third-party library that changes how cypress works with async/await, like cypress-promise. This lib may help you to treat cypress commands as promises that you can await in your before code (read more about it in this article).

    这篇关于Cypress.io如何处理异步代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆