【问题标题】:When should we use .then with Protractor Promise?我们什么时候应该将 .then 与 Protractor Promise 一起使用?
【发布时间】:2015-06-02 14:24:13
【问题描述】:

我在使用 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())时,我在浏览器上看到 没有完成对按钮的点击,测试会按照以下预期继续,然后停止。

如果我使用 .then() 表单,按钮的点击就完成了,测试继续没有错误。

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

那么,我应该什么时候使用 .then() 而什么时候不应该呢?

让-马克

【问题讨论】:

    标签: promise protractor


    【解决方案1】:

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

    那是:

    1. Protractor 将 ControlFlow 中的所有驱动程序命令排入队列,
    2. 当您需要驱动程序命令的结果时,您应该使用 .then,
    3. 当您不需要驱动程序的结果时,您可以避免。那么,但所有 以下指令必须在 ControlFlow 中排队,否则它们 将在队列中的命令之前运行导致不可预测 结果。因此,如果要运行非驱动程序测试命令,则应将其添加到 .then 回调或将测试包装到 Promise 中并将测试排入 ControlFlow 中。请参见下面的示例。

    这是我的测试在没有 .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
    

    【讨论】:

    • 如果你直接调用 testAccount()(没有 browser.controlFlow 的东西),testX 的输出会有什么不同?
    • 另外,为什么需要 browser.wait?
    • 如果 testAccount 被直接调用,有时你有正确的顺序,有时不取决于浏览器或机器的速度。你可以有类似 0, 1, 2, 3, 5, 6, 4 的东西,或者测试 expect(message.isPresent()).to.be.eventually.true 可以在 testAccount 调用之后进行评估
    • browser.wait(EC.visibilityOf(message), 5000);是 Protractor 1.7 中的一个新功能,它等待元素的可见性。例如,如果您的元素可以通过延迟动画更改可见性,这将非常有用。
    【解决方案2】:

    帮自己一个忙,避免.then

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

    但简而言之,打开 protractor API 页面https://www.protractortest.org/#/api,找到你要使用的方法,看看它返回什么。如果它说承诺,只需在调用它之前添加await。确保,使您的包装功能async

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

    【讨论】:

      猜你喜欢
      • 2021-09-07
      • 1970-01-01
      • 2011-07-04
      • 2017-09-13
      • 2021-12-29
      • 2011-07-17
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多