量角器:我是否过度使用了promise.then()

Protractor: Am I overusing promise.then()

本文关键字:promise then 是否 量角器      更新时间:2023-09-26

我正在使用量角器进行端到端测试。我正在处理的应用程序部分首先使用 ng-switch 语句在注册过程中显示/隐藏问题,一次一个。问题之间的动画给了我最难的时光。例如,尝试加载页面>转到下一个问题>断言元素存在是很困难的,除其他外。该脚本将加载页面,单击"下一步"按钮,然后在下一张幻灯片出现在屏幕上之前进行断言。

更糟糕的是,在问题之间的大约半秒钟内,旧问题和新问题都存在于DOM上。我能想到的最好的非睡眠等待机制是做一个browser.wait(),它首先等待DOM上有两个问题,然后链接另一个browser.wait(),等待DOM上只有一个问题,然后从那里继续。(整个操作在代码中包装到 registerPage.waitForTransition() 中)

browser.wait()s并不总是阻塞足够长的时间,所以我最终编写了如下所示的代码:

it('moves to previous question after clicking previous link', function() {
    var title;
    // Get the current slide title, then click previous, wait for transition,
    // then check the title again to make sure it changed
    registerPage.slideTitle.getText()
        .then(function(text) {
            title = text;
        })
        .then(registerPage.prevLink.click())
        .then(registerPage.waitForTransition())
        .then(function() {
            expect(registerPage.slideTitle.getText()).not.toBe(title);
        });
});

以确保在执行下一个命令之前正确完成每次等待。现在这完美地工作。之前发生的事情是,测试将在 95% 的时间内成功,但在转换实际 100% 完成之前,偶尔会触发断言或下一次点击操作等。这不再发生,但我觉得这几乎是在承诺上过度使用 .then()。但与此同时,强制所有内容按顺序发生是有意义的,因为这就是与网站交互的实际工作方式。加载页面,然后等待下一个按钮滑入,然后进行选择,然后单击下一个按钮,然后等待下一张幻灯片,依此类推。

我是以一种完全糟糕的练习风格这样做,还是在具有大量动画的应用程序上使用量角器时可以接受的承诺使用?

我喜欢

这种类似代码审查的问题,所以感谢您的发布。

我确实认为你的一些.then是不必要的。.click()expect不需要它们,因为它们应该添加到controlFlow中。expect也应该处理你getText()的承诺。

您遇到的问题似乎在您的waitForTransition()方法范围内,在controlFlow之外操作。根据您在此方法中处理等待的方式,您可能需要自己将其添加到controlFlow中。例如。您是否正在调用非 Web 驱动程序命令?在这种情况下,我也很幸运地使用Expected Conditions isClickable()

此外,我还会将大部分代码卸载到您的页面对象,尤其是在需要等待时。例如,如果将类似以下内容添加到页面对象:

注册页面:

this.getSlideTitleText = function() {
    return this.slideTitle.getText().then(function(text) {
        return text;
    });
};
this.clickPrevLink = function() {
    this.prevLink.click();
    return this.waitForTransition(); // fix this and the rest should work
};

那么你的测试可能是...

it('moves to previous question after clicking previous link', function() {
    var title = registerPage.getSlideTitleText();
    registerPage.clickPrevLink();
    expect(registerPage.getSlideTitleText()).not.toBe(title);
});