为什么我需要使用 waitForAngular(false) & browser.sleep(3000)?

Why do I need to use waitForAngular(false) & browser.sleep(3000)?

我们有一个 100% 由 Angular 构建的网站,我被要求使用 Protractor 编写端到端测试。现在遇到一个问题,如果我不使用 waitForAngular(false)browser.sleep(3000) 那么即使我使用 ExpectedCondition.

我的测试也会失败

这是我的场景:

在登录页面中,我可以找到所有元素,将键发送到输入框并登录。但是登录后,它失败了。它找不到任何元素,请单击任何元素。

我的代码是这样的。

describe("/profile", () => {
  let page: Profile;

  beforeAll(async () => {
    page = await login(Profile, user, login);
    await browser.wait(ExpectedConditions.presenceOf(page.element));
    await navigate(path.profile)
  })

  afterAll(async () => {
    logout();
  })

  it("should have navigate to the page", async () => {
    expect(await browser.getCurrentUrl()).toContain("/profile");
  });

  it("should have correct page markup", async () => { 
// this test fails without waitForAngular(false)
// or browser.sleep(3000) in the navigation or OnPrepare in the config
    expect(await page.headerTitle.isDisplayed()).toBe(true);
    expect(await page.headerTitle.getText()).toContain("Profile")
  })
})

我做错了什么?

正如我从评论中了解到的那样,在您的应用程序(应使用量角器进行测试)上,您有 setIntervalsetTimeout 或 long-运行 并重复执行异步操作。

在 Protractor 执行任何测试规范之前,它会尝试等待 Angular 2 应用“同步”,即完成所有未完成的操作。默认情况下,Protractor 定义了 11 秒的超时时间。

由于您有一些 "infinite" 操作 - 同步失败并且量角器因超时错误而停止执行。

您可以使用 Zone.js 来避免这种情况:

ngZone.runOutsideAngular(() => {
    setInterval(() => {
        ngZone.run(() => {
            // async operation
        });
    }, 2500);

与您的开发人员一起调查此问题。

来源:https://christianliebel.com/2016/11/angular-2-protractor-timeout-heres-fix/

首先,browser.wait()接受三个参数——功能条件、超时、失败消息。只有最后一个是可选的。您忘记以毫秒为单位指定超时时间,这可能会导致您的问题

其次,waitForAngular采用可选字符串作为描述。不知道你为什么把 false 传给它

P.S。 我认为您误解了有关如何在量角器中处理等待的主要概念

browser.sleep(ms) - 是显式等待,停止执行指定为参数的毫秒数

browser.wait() - 等待直到传递给它的函数 returns 为真,或者等待作为参数传递的毫秒数。这不是明确的等待。此外,它不会无限期地等待。您将超时时间作为参数传递,或者它需要 protractor.conf.js 中的 jasmineNodeOpts.defaultTimeoutInterval 或默认的 30 秒

您的 browser.sleep(ms) 导致您的测试出现性能问题。在你的测试中避免它

browser.waitForAngular() - 非常有用,它会等到您的 angular 应用在后台完成所有任务,但默认情况下它包含在每个操作中。因此,如果您使用 2,3 或 4 次,通常不会有任何影响。重要提示,有些应用程序构建不佳并且总是在后台加载某些内容,因此您的测试要么很慢要么根本没有响应。这就是为什么我总是 运行 使用 browser.waitForAngularEnabled(false) 进行测试,但处理等待非常困难。作为一个优势,您可以获得快速可靠的测试。并且不要将 false 传递给 waitForAngular,它没有任何效果。

话虽如此,忘记 browser.sleep() 而是学习如何使用 browser.wait

如果您使用 browser.sleep(3000),您会让测试停止 3 秒,但是如果您的下一个元素准备好在 500 毫秒内与之交互怎么办?所以只要说等到元素出现(可见(难处理(或任何你想要的))),但不超过 3 秒,你最终会有更快的测试

希望这能回答您的问题