如何避免在每一行上使用await

时间:2019-06-17 22:57:57

标签: angular typescript protractor

使用量角器进行端到端测试时,似乎SELENIUM_PROMISE_MANAGER: false的每一行代码都需要等待。

下面有没有更好的方法来做这个例子?

最初我使用的是SELENIUM_PROMISE_MANAGER: false,但是在需要使用条件WebElement.isPresent()时遇到了问题。承诺管理器无法解决isPresent()的承诺,只能继续执行。因此,现在考虑使用async / await。

describe('Home Page', async () => {

  beforeAll(async () => {
    await loginPage.loadPage();  // methods defined in Page Object
    await loginPage.login();     // uses WebElement.sendKeys() and Webelement.submit()
    await homePage.closeModal();
  });

  it('should fill a form', async () => {
    await $('#field1').clear();
    await $('#field1').sendKeys('hello');
    await $('#field2').clear();
    await $('#field2').sendKeys('world');
    $('form').submit();
  }
}

如果几乎​​每行都需要等待,那么我在这里缺少什么吗?

2 个答案:

答案 0 :(得分:2)

使用异步/等待时,除了在调用每个函数之前放await之外,别无其他方法,因为在进行E2E测试时,您需要确保所有内容都以特定顺序运行。
在您的特定情况下,您还可以在1个单个函数中声明所有内容。

//declare this somewhere else:
this.formFill = async () => {
    await $('#field1').clear();
    await $('#field1').sendKeys('hello');
    await $('#field2').clear();
    await $('#field2').sendKeys('world');
    await $('form').submit();
};  

然后在it块中调用它:

it('should fill a form', async () => {
    await this.formFill();
});

答案 1 :(得分:1)

我们无法避免,因为有充分的理由。首先,我们需要了解 JavaScript是异步编程语言。最初使用量角器时,我们不得不使用 Promises()来编写端到端测试用例,由于承诺链(多个'then'),很难理解和调试测试代码。 。为了解决此问题,量角器引入了 Promise Manger 。它解决了promise链的问题,但是调试测试代码很困难,我们需要采取一些明确的措施来调试测试代码。     当ES2017引入async / await时,它实际上解决了Promises链接的问题,因此无需编写

 Using Promises 
        A().then( () => {
             B().then( () => {
                   C().then( () => {
                          });
                       });
                   });

Using async/await
     async func() {
       await A();
       await B();
       await C();
     }

这里的等待角色是什么? 函数A(),B(),C()仍返回Promise的对象,但内部等待Promise解析/拒绝,然后再移至下一行。一旦Promise解决,它将获得值,然后执行下一行。因此,异步/等待对于在返回Promise的每个函数之前进行编写很重要。

让我们来看看您提到的代码

等待loginPage.login(); -> WebElement.sendKeys();和Webelement.submit();

如果我们在IWebelement类中检查sendKeys()和Submit()函数的定义,则它看起来像

    sendKeys(...var_args: Array<string|number|promise.Promise<string|number>>): promise.Promise<void>;

    submit(): promise.Promise<void>;

在前面的代码片段中,我们可以看到两个函数都返回Promise。如果我们在此之前不使用await,那么它将无法正确执行代码并移至下一行。

结论是要避免还是不避免'await'取决于函数的返回类型。如果没有承诺,则可以避免;如果函数返回promise,则永远不要避免。