如果没有done()方法,则无法通过我的测试



我实际上正在完成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');
    });
});

最新更新