使用量角器进行AngularJS测试 - 执行异步脚本



我正在开发一套自动化测试,使用量角器在AngularJS应用程序上运行。在完成此任务之前,我从未使用过自动化测试,因此我仍然不熟悉它的工作原理/如何实现测试等。

我最近在实现自动单击对话框的"取消"按钮时遇到了一些麻烦,当其中一个测试浏览到特定页面时,该对话框会自动显示。

我现在已经单击"取消"按钮成功工作,但由于异步回调错误,测试脚本仍然失败。

测试脚本编写如下:

it('should navigate to the Charts page', function(done) {
console.log("Start Charts page test");
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(chartsMenuBtn).perform();
chartsMenuBtn.click();
browser.waitForAngularEnabled(true);
//browser.sleep(5000);
browser.call(closeDlg);
//var closeDlgFn = closeDlg();
//browser.wait(closeDlgFn, 5 * 1000, 'Dialog should close within 5 seconds');
console.log("End Charts page test");
expect(browser.getCurrentUrl()).toBe('http://192.168.1.212:8080/#/charts');
});

脚本中调用的closeDlg()函数定义如下:

function closeDlg(){
browser.waitForAngularEnabled(false);
console.log("closeDlg() function called ")
var EC = protractor.ExpectedConditions;
var chartConfigForm = element(by.id('chartConfigForm'));
var closeDlgBtn = element(by.id('editGraphCancelBtn'));
console.log("About to click closeDlgBtn ");
closeDlgBtn.click();
console.log("just clicked closeDlgBtn ");
console.log("End of closeDlg() function ")
}

browser.call(closeDlg).then(function(){console.log("End Charts page test"); done();});

当我按当前状态运行脚本时,我在命令行中得到以下输出:

."开始图表"页面测试

结束图表页面测试

-- 下一个命令:查找元素

-- 下一个命令:鼠标移动到

-- 下一个命令:查找元素

-- 下一个命令:单击元素

closeDlg() 函数调用

即将单击关闭DlgBtn

刚刚点击关闭DlgBtn

closeDlg() 函数结束 -- 下一个命令:查找元素

显示全部内容后,对话框当前仍在浏览器中打开。当我继续逐步完成测试时,我在命令行中收到以下两个提示:

-- 下一个命令:单击元素

结束图表页面测试

-- 下一个命令:执行异步脚本

这就是对话框关闭的时候。

如果我继续执行我的测试脚本,我会失败:

FA 茉莉花规格超时。重置 Web 驱动程序控制流。

茉莉花规格超时。重置 Web 驱动程序控制流。

失败:

1)应用程序应导航到图表页面

消息:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

叠:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. at ontimeout (timers.js:386:11) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5)

消息:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

叠:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. at ontimeout (timers.js:386:11) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5)

5 个规格,1 个故障

在260.014秒内完成

我在网上找到的所有内容似乎都表明我应该在jasmine.js中增加j$.DEFAULT_TIMEOUT_INTERVAL变量的值,我已经做到了 - 我已将其从 10000(默认值)增加到 500000。

我还在conf.js文件中添加了一个allScriptsTimeout值:

exports.config = {
framework: 'jasmine',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['spec.js'], // List all of the different files in which the tests are defined here
allScriptsTimeout: 120000,
onPrepare: function() {
browser.addMockModule('disableModalAnimations', function(){
angular.module('disableModalAnimations', []).value('foo', 'bar');
});
},
multiCapabilities: {
browserName: 'firefox'
}
}

我不明白为什么我会收到这个超时错误?

我尝试将测试脚本中对closeDlg()的调用更改为:

browser.call(closeDlg).then(function(){console.log("End Charts page test"); done();});

但仍然得到相同的错误。

我怀疑这个问题实际上是超时问题,但我不确定我是否正确执行异步脚本。

谁能发现我在这里做错了什么?错误告诉我的异步回调在指定的超时时间内未调用是什么?我正在做的哪一部分是异步的?

因此,在对代码进行了大量混乱,砍伐和更改,尝试了不同的方法,并在网上查看了各种文章以获取有关如何执行此操作的建议之后,我终于通过将测试的expect子句放在链接到对我的closeDlg()函数调用的.then()函数中(并将其从测试的it()级别中删除):

it('should navigate to the Charts page', function() {
console.log("Start Charts page test");
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(chartsMenuBtn).perform();
chartsMenuBtn.click();
browser.waitForAngularEnabled(true);
browser.call(closeDlg).then(function(){
expect(browser.getCurrentUrl()).toBe('http://192.168.1.212:8080/#/alarms');
});

此测试现在正确通过,并且逐步完成,我可以看到它按预期执行命令,并产生正确的结果。

虽然你自己回答了,但我会添加一些信息:

  • 承诺按哪个顺序解决,可以在这里找到
  • 这个答案在这里解释了,browser.call()是用来做什么的。

在我看来,只有函数调用,您的browser.call()毫无意义。它甚至很可能导致您的问题,因为它将您调用的函数添加到 controlFlow 的末尾,导致在执行其他所有内容后最终执行它。

此外,您的关闭/打开/关闭browser.waitForAngularEnabled()也令人困惑。我建议根本不打开它,因为它可能是您一开始关闭它的原因。

通过在浏览器调用后使用then(),您可以强制expect部分在browser.call()之后执行。虽然你没有解决你遇到的问题,但你通过强制其他代码行在你的"问题"行后面来解决它。

阅读您的代码,我认为没有任何理由使用browser.call().

var closeDlgPage = require('[relativePathTo]/closeDlgPage.js'); 
it('should navigate to the Charts page', function(done) {
console.log("Start Charts page test");
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(chartsMenuBtn).perform();
chartsMenuBtn.click();
//browser.waitForAngularEnabled(true);
closeDlgPage.closeDlg();
console.log("End Charts page test");
expect(browser.getCurrentUrl()).toBe('http://192.168.1.212:8080/#/charts');
});

和您的closeDlg()(您当然可以删除所有console.log()以使其更短:

//look how PageObjects in Protractor work, if this looks new to you.
closeDlgPage= function(){
this.closeDlg = function(){
console.log("closeDlg() function called ");
//var EC = protractor.ExpectedConditions; //You're not using EC in this function. 
var chartConfigForm = element(by.id('chartConfigForm'));
var closeDlgBtn = element(by.id('editGraphCancelBtn'));
console.log("About to click closeDlgBtn ");
closeDlgBtn.click();
console.log("just clicked closeDlgBtn ");
console.log("End of closeDlg() function ")
};
};
module.exports = new closeDlgPage();

最新更新