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

问题描述 投票:0回答:3

使用Protractor进行E2E测试时,似乎每行代码都需要await,当

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();
  }
}

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

angular typescript protractor
3个回答
3
投票

使用 async/await 时,除了在调用每个函数之前放置

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
投票

我们无法避免它,因为它有充分的理由。首先我们需要了解JavaScript是异步编程语言。当量角器最初使用时,我们必须使用Promises()来编写端到端测试用例,并且由于 Promise 链(多个“then”),很难理解和调试测试代码。为了克服这个问题 Protractor 引入了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();
     }

await在这里的作用是什么? 函数 A()、B()、C() 仍然返回 Promise 的对象,但在内部等待 Promise 解析/拒绝,然后再移动到下一行。一旦 Promise 解析,它就会获取值然后执行下一行。因此,在每个返回 Promise 的函数之前编写 async/await 非常重要。

让我们看一下您提到的代码

等待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”取决于函数的返回类型。如果它不是承诺,那么你可以避免,如果函数返回承诺,那么永远不要避免它。


0
投票

你可以到处写所有“等待”,但最终它不会更容易阅读和支持。

只是为了练习。有了这个:

await $('#field1').clear();
await $('#field1').sendKeys('hello');
await $('#field2').clear();
await $('#field2').sendKeys('world');

可以转化为操作的定义。

[
['#field1', $.clear, undefined],
['#field1', $.sendKeys, 'hello'],
['#field2', $.clear, undefined],
['#field2', $.sendKeys, 'world'],
]

然后通过一些东西来一一等待他们......这不是更好。是的? :D

(代码仅用于概念)

© www.soinside.com 2019 - 2024. All rights reserved.