我维护了一个复杂的Angular(1.5.x)应用程序,该应用程序正在使用Protractor(2.5.x)进行E2E测试。我遇到了这种方法的问题,主要表现在测试看起来很脆弱的方式。在一个拉取请求中完美运行的测试在另一个拉取请求中失败。这涉及简单的定位器,例如by.linkTest(...)。我调试了失败的测试,应用程序位于正确的页面上,链接存在且可访问。
还有其他人遇到过这些一致性问题吗?了解原因或解决方法?
答案 0 :(得分:11)
Just Say No to More End-to-End Tests!
那就是说,这里有一些你可以做的事情来解决我们共同的无情" flakiness"敌人:
selenium
和chromedriver
使用龙 browser.wait()
并使用一组built-in or custom Expected Conditions。这可能是迄今为止解决问题的最可靠方法。不幸的是,这是用例和特定问题,您需要在有问题的地方修改您的实际测试。例如,如果您需要单击某个元素,请等待它可单击:
var EC = protractor.ExpectedConditions;
var elm = $("#myid");
browser.wait(EC.elementToBeClickable(elm), 5000);
elm.click();
最大化浏览器窗口(以避免随机元素不可见或不可点击的错误)。把它放到onPrepare()
:
browser.driver.manage().window().maximize();
browser.waitForAngular();
。我不确定为什么这会有所帮助,但我已经看到报告肯定有助于修复一个不稳定的测试。done()
callback。例如,这可能有助于在it()
done
之前不启动beforeEach()
阻止
onPrepare()
function。这通常有助于确保为测试运行做好准备protractor-flake
package 。更像是对问题的快速解决方法还有其他特定问题的"技巧"例如slow typing into the text box,点击via JavaScript等
答案 1 :(得分: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()
。
答案 2 :(得分:1)
根据我的经验,某些方法(例如sendKeys()
)并不总是在controlFlow()
队列中的预期时间触发,并且导致测试变得松懈。我通过专门将它们添加到controlFlow()
来解决这个问题。例如:
this.enterText = function(input, text) {
return browser.controlFlow().execute(function() {
input.sendKeys(text);
});
};
答案 3 :(得分:1)
我的团队一直使用的解决方法是使用插件protractor-errors重新运行失败的测试。使用此工具,我们可以在2-3次运行中识别真实故障与flakey测试。要添加插件,只需在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。