什么时候我们应该使用.then和Protractor Promise?

时间:2015-03-29 16:11:53

标签: promise protractor

我和Protractor有很多不稳定因素,我确信有一些我不理解的东西。 有时我需要在继续之前单击按钮时使用.then(),有时它没有任何影响,我不应该使用.then()或测试失败。

我想知道在Protractor中测试时我应该何时使用.then()回调? 示例:

createAccountForm = $('#form-create-account');
submitButton = createAccountForm.$('button[type=submit]');

browser.wait(EC.elementToBeClickable(submitButton), 5000);
submitButton.click(); // .then(function(){   <-- uncomment in the .then form

// find the confirmation message
var message = $('.alert-success');
browser.wait(EC.visibilityOf(message), 5000);
log.debug('After visibilityOf');

expect(message.isPresent()).to.be.eventually.true;
// }); --> uncomment when in .then form

当我使用这种形式的测试时(没有.then())我在浏览器上看到点击按钮没有完成,测试继续以下期望然后停止。< / p>

如果我使用.then()表单,则单击按钮,测试继续且没有错误。

在其他测试中,单击按钮时我不需要使用then()回调。

那么,我何时应该使用.then(),何时不使用?

让马克

2 个答案:

答案 0 :(得分:40)

这个问题的答案可以在这篇文章中找到:http://spin.atomicobject.com/2014/12/17/asynchronous-testing-protractor-angular/

那是:

  1. Protractor将所有驱动程序命令排入ControlFlow,
  2. 当您需要驱动程序命令的结果时,您应该使用.then,
  3. 当你不需要驾驶员的结果时,你可以避免。然后全部 以下说明必须在ControlFlow中排队,否则就行了 将在队列中的命令之前运行,导致不可预测 结果。因此,如果要运行非驱动程序测试命令,则应将其添加到.then回调中,或将测试包装到Promise中并将测试排入ControlFlow。见下面的例子。
  4. 这是我的测试工作的一个例子,没有.then:

    log.debug('test0');
    
    // enqueue the click
    submitButton.click(); 
    var message = $('.alert-success'); 
    
    // enqueue the wait for message to be visible  
    browser.wait(EC.visibilityOf(message), 5000);  
    
    log.debug('test1');
    
    // enqueue a test
    expect(message.isPresent()).to.be.eventually.true;
    log.debug('test2');
    
    // a function returning a promise that does an async test (check in MongoDB Collection)
    var testAccount = function () {           
        var deferred = protractor.promise.defer();
    
        // Verify that an account has been created
        accountColl.find({}).toArray(function (err, accs) {
            log.debug('test5');
            expect(err).to.not.exist;
            log.debug('test6');
            expect(accs.length).to.equal(1);
            return deferred.fulfill();
        });
        return deferred.promise;
    };
    
    log.debug('test3');
    
    // Enqueue the testAccount function
    browser.controlFlow().execute(testAccount);  
    log.debug('test4');
    

    输出现在是我们所期望的:

    test0
    
    test1
    
    test2
    
    test3
    
    test4
    
    test5
    
    test6
    

答案 1 :(得分:1)

帮自己一个忙,避免.then

今天,async/await 更适合处理承诺

但简而言之,打开量角器 API 页面 https://www.protractortest.org/#/api,找到您将要使用的方法并查看它返回的内容。如果它说 promise,只需在调用它之前添加 await。确保,使您的包装功能 async

it('test case 1', async () => {
  await elem.click()
})