12

我维护一个复杂的 Angular (1.5.x) 应用程序,该应用程序正在使用 Protractor (2.5.x) 进行 E2E 测试。我在使用这种方法时遇到了问题,主要表现为测试看起来不稳定。在一个拉取请求中运行良好的测试在另一个请求中失败。这涉及简单的定位器,例如 by.linkTest(...)。我调试了失败的测试,应用程序位于正确的页面上,链接存在且可访问。

有没有其他人遇到过这些一致性问题?知道原因或解决方法吗?

4

4 回答 4

14

对更多的端到端测试说不!

也就是说,您可以采取以下几项措施来解决我们共同无情的“脆弱”敌人:

  • 更新到最新的量角器(当前为 4.0.0),它也带来了最新的seleniumchromedriver
  • 关闭 Angular 动画
  • 使用带有一组内置或自定义预期条件的 。这可能是迄今为止解决问题的最可靠方法。不幸的是,这是特定于用例和问题的,您需要在有问题的地方修改您的实际测试。例如,如果您需要单击一个元素,请等待它可单击:browser.wait()

    var EC = protractor.ExpectedConditions;
    var elm = $("#myid");
    
    browser.wait(EC.elementToBeClickable(elm), 5000);
    elm.click();
    
  • 最大化浏览器窗口(以避免随机元素不可见或不可点击错误)。把这个放到onPrepare()

    browser.driver.manage().window().maximize();
    
  • 增加量角器和茉莉花超时
  • 通过调整控制流来减慢量角器(不确定它是否适用于 4.0.0,请测试)
  • 手动调用browser.waitForAngular();有问题的地方。我不知道为什么这会有所帮助,但我已经看到报告说它肯定有助于修复一个不稳定的测试。
  • 在您的规范中使用jasminedone()回调。例如,这可能有助于在调用it()之前不启动块donebeforeEach()
  • onPrepare()函数返回一个承诺。这通常有助于确保为测试运行做好准备
  • 使用会自动重新运行失败测试的protractor-flake。更像是解决问题的快速解决方法

还有其他针对特定问题的“技巧”,例如在文本框中输入缓慢、通过 JavaScript 进行点击等。

于 2016-07-26T13:47:14.083 回答
2

是的,我认为我们所有人都经历过这种脆弱的问题。

实际上,任何浏览器自动化工具都会出现片状问题。但是,在 Protractor 的情况下,这应该更少,因为 Protractor 具有内置的等待考虑,它仅在正确加载 dom 后才执行操作。但是,在少数情况下,如果您看到间歇性故障,您可能不得不使用一些显式等待。

我更喜欢使用一些智能等待方法,例如:

function waitForElementToClickable(locator) {
        var domElement = element(by.css(locator)),
            isClickable = protractor.ExpectedConditions.elementToBeClickable(domElement);

        return browser.wait(isClickable, 2000)
            .then(function () {
                return domElement;
            });
    }

在将 2000 毫秒用作超时的情况下,您可以使用变量对其进行配置。有时,browser.sleep()当我的智能等待都不起作用时,我也会选择。

于 2016-07-26T11:43:48.357 回答
1

我的团队一直在使用的一种解决方法是使用插件protractor-errors仅重新运行失败的测试。使用这个工具,我们可以在 2-3 次运行中识别出真正的失败和易碎测试。要添加插件,只需在 Protractor 配置的 onPrepare 函数底部添加一个 require 语句:

exports.config = {
    ...

    onPrepare: function() {
      require('protractor-errors');
    }
}

使用插件运行测试时,您需要传递这些附加参数:

protractor config.js --params.errorsPath 'jasmineReports' --params.currentTime (timestamp) --params.errorRun (true or false)

如果您没有简单的方法来传递时间戳,还有一个 cli 工具将处理生成 currentTime。

于 2017-02-21T14:12:35.147 回答
1

根据我的经验,某些方法(例如sendKeys())并不总是在controlFlow()队列中的预期时间触发,并且会导致测试变得不稳定。我通过专门将它们添加到controlFlow(). 例如:

this.enterText = function(input, text) {
    return browser.controlFlow().execute(function() {
        input.sendKeys(text);
    });
};
于 2016-07-27T19:33:46.200 回答