我实际上正在完成Angular应用程序的单元测试。我目前正在使用Protractor和Jasmine进行E2E测试。不幸的是,我有以下问题:
我在网上做了大量的研究,比如http://ramonvictor.github.io/protractor/slides/#/1很明显,我从未见过使用"done"回调来启动测试。
第一个测试在createUser页面上进行,并确保用户选项卡属性设置为active。只有当我使用done方法时,它才通过,而我不应该使用它。
'use strict';
var UserCreate = require('./page-objects/userCreate.pageObjects');
describe('on init', function () {
beforeEach(function() {
var rootUrl = browser.baseUrl + '/#/users/create';
browser.driver.get(rootUrl);
});
it('should set the user tab active', function(done) { // DONE callback
UserCreate.tabs.getAttribute('class').then(function(value) {
expect(value).toEqual('active');
done(); // calling callback
});
});
});
如果我在不使用done()的情况下重复相同的测试,即使这次我希望它失败,测试也会通过。
'use strict';
var UserCreate = require('./page-objects/userCreate.pageObjects');
describe('on init', function () {
beforeEach(function() {
var rootUrl = browser.baseUrl + '/#/users/create';
browser.driver.get(rootUrl);
});
it('should set the user tab active', function() {
UserCreate.tabs.getAttribute('class').then(function(value) {
expect(value).toEqual('activeWRONG');
});
});
});
只有当我使用done回调时,它才会失败。
这是我的配置文件:
/* conf.js */
' use strict';
exports.config = {
rootElement: '#myApp',
directConnect: true,
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: {
browserName: 'chrome',
shardTestFiles: true,
maxInstances: 1
},
framework: 'jasmine',
// specs: ['./*.spec.js'],
baseUrl: 'http://localhost:9001',
defaultTimeoutInterval: 0000,
jasmineNodeOpts: {
showColors: true,
},
suites: {
wip: './userCreate.spec.js',
all: './*spec.js'
},
onPrepare: function() {
browser.driver.get('http://localhost:9001/#/');
element(by.id('ld-link-login')).click();
browser.sleep(500);
element(by.model('username')).sendKeys('test');
element(by.model('password')).sendKeys('test');
element(by.id('nv-login-submit')).click();
return browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return /dashboard/.test(url);
});
}, 10000);
}
};
我在使用done无处不在的深层测试中遇到了异步问题,所以我想在继续测试之前解决这个问题。
谢谢你的帮助。
编辑:
量角器版本:/node_modules/.bin/量角器——版本给出版本3.2.2
userCreate.pageObjects:
'use strict';
module.exports = {
tabs: element(by.id('cc-tab-user'))
};
这是预期的行为。如果您不要求使用done()
函数,jasmine会认为您的测试是同步的,并在不等待承诺得到解决的情况下完成。当您请求它时,您的测试变为异步的,并且如果在超时(默认情况下为5秒)之前没有调用done()
,则测试将失败请参阅:http://jasmine.github.io/2.0/introduction.html#section-异步_支持以获取更多信息。
您在定义页面对象时遇到问题,导致promise解决顺序出现问题。遵循样式指南并将其更改为:
var UserCreatePage = function() {
this.tabs = element(by.id('cc-tab-user'));
};
module.exports = UserCreatePage;
用法:
'use strict';
var UserCreatePage = require('./page-objects/userCreate.pageObjects');
describe('on init', function () {
var userCreatePage;
beforeEach(function() {
var rootUrl = browser.baseUrl + '/#/users/create';
browser.driver.get(rootUrl);
userCreatePage = new UserCreatePage();
});
it('should set the user tab active', function() {
userCreatePage.tabs.getAttribute('class').then(function(value) {
expect(value).toEqual('activeWRONG');
});
});
});
如果您的测试在测试的控制流中创建了一个并行的TaskQueue,就会发生这种行为。关于done()的用途以及如何使用它(量角器,jasmine),我写了几个测试示例,因此给出了不一致的结果。
要弄清楚这是否是你的问题,你可以打印出测试中各个点的控制流程:
console.log(protractor.promise.controlFlow().getSchedule(false));
您的问题是,使用then()
将value
传递给expect
-语句。then()
创建一个新的异步任务,该任务作为子任务被删除。因此,it
首先以result=success结束,然后执行expect语句。它在Selenium的Promise/ControlFlow文档中进行了记录。
由于expect()
已经打开/解决了一个承诺,因此在您的情况下不需要then()
。
对于done
,它是有效的,因为您可以控制执行,并在then()
完成之前阻止it
继续/完成。
试试这个:
'use strict';
var UserCreate = require('./page-objects/userCreate.pageObjects');
describe('on init', function () {
beforeEach(function() {
var rootUrl = browser.baseUrl + '/#/users/create';
browser.driver.get(rootUrl);
});
it('should set the user tab active', function() {
expect(UserCreate.tabs.getAttribute('class')).toEqual('activeWRONG');
});
});
这是因为控制流在代码中运行不正常。控制流基于任务和任务队列的概念。任务是定义控制流要执行的基本工作单元的函数。每个任务都是通过ControlFlow#execute()进行调度的,它将返回一个ManagedPromise,该消息将与任务的结果一起解决。
以下内容应该有效。
let UserCreate = require('./pageobject.page.js');
describe('should navigate to url', function () {
beforeEach(function() {
url = `${browser.baseUrl}/#/users/create`;
browser.driver.get(url);
});
it('should set the user tab active', function() {
expect(UserCreate.tabs.getAttribute('class')).toEqual('activeWRONG');
});
});