【问题标题】:How do I mix, expect() with non-protractor promises in protractor promise chains?如何在量角器承诺链中将 expect() 与非量角器承诺混合?
【发布时间】:2019-06-18 02:37:47
【问题描述】:

我试图了解如何(以什么顺序)在量角器中执行承诺,特别是对于与量角器承诺混合的非量角器承诺(例如 native 或 q 承诺)。 我在工作中调试和修复一些不稳定的量角器测试,而且我绝不是一个 JavaScript 程序员。所以在给出你的答案时,假设你的答案会超越我的头脑并将其降低一两个级别。

在使用特定的易碎测试几天没有运气之后,我决定编写一些非常简单的示例来尝试了解承诺链是如何执行的。 根据我在网上阅读的内容,我认为链接是这样的:

a().then(() => {
    x();
    b().then(() => {
        y();
        c().then(() => z());
    });
});

应该与:

a().then(() => {
    x();
    b();
}).then(() => {
    y();
    c();
}).then(() => z());

这也应该与此相同(如果我在工作中使用 ES6,我不是):

await a();
await x();
await b();
await y();
await c();
await z();

您可以在此处查看我的完整代码以及我得到的输出: https://github.com/cpjust/TypeScriptTest/tree/dev/specs

对于所有这些场景,以及在使用原生 Promise 与 Protractor Promise 时,我得到了不同的结果。 在 second_spec.ts 中,我还尝试在应该失败的 Promise 中添加 expect() 语句,并且我期望在 expect() 之后链接的 Promise 不会执行,因为 Expect 应该抛出一个断言错误,但我看到的是所有执行后承诺,但由于 expect() 失败,测试仍然失败。很奇怪……

【问题讨论】:

    标签: javascript typescript jasmine protractor


    【解决方案1】:

    您的一个问题包含许多子问题,但都很好。所以最好一个一个去,我会尽力解释,这可能会帮助你解决你的问题。

    first_spec.ts

     it('promise chain 1', function () {
            /* Prints the following:
            [TRACE] default - Start
            [DEBUG] default - Sleeping for 100 ms...
            [TRACE] default - End
            [INFO] default - --1
            [DEBUG] default - Sleeping for 200 ms...
            [INFO] default - --2
            [DEBUG] default - Sleeping for 300 ms...
            [INFO] default - --3
            [INFO] default - --done
            */
            logger.trace("Start");
    
            printLater("--1", 100).then(() => {
                printLater("--2", 200).then(() => {
                    printLater("--3", 300).thenFinally(() => {
                        logger.info("--done");
                    });
                });
            });
    
            logger.trace("End");
        });
    
    • 这个非常直接。 printLater 返回promise browser.sleep,所以它必须等待给定的时间然后让它解决。这意味着每一个 printLater 都必须在进行下一个之前完成。我希望你不要怀疑它会阻塞。

      it('承诺链 1.1', function () { /* 打印以下内容: [TRACE] 默认 - 开始 [DEBUG] 默认 - 休眠 100 毫秒... [TRACE] 默认 - 结束 [信息] 默认 - --1 */ logger.trace("开始");

          nativePromise("--1", 100).then(() => {
              nativePromise("--2", 200).then(() => {
                  nativePromise("--3", 300).finally(() => {
                      logger.info("--done");
                  });
              });
          });
      
          logger.trace("End");
      });
      

    在这种情况下,nativePromise 创建 Promise 对象并在其中调用 printLater。让我解释一下流程是如何发生的。 当我们调用函数nativePromise时,它直接返回当前处于默认挂起状态的promise对象(因为任何promise对象resolve/reject/pending都有三种状态)。现在在nativePromise上使用then期望resolve/reject状态但它仍然处于待定状态无限期直到测试超时。这就是测试在某一点发生并且不做任何事情的原因。最后一点是,由于异步行为,我们得到了第一个 nativePromise 的一些输出。因为有 printLater 函数异步工作并记录其结果。

    使其与第一次阻塞相同的简单方法是对 nativePromise 函数进行轻微更改。你必须使用 resolve 来确保这个 Promise 被解决。

    function nativePromise(msg, time) {
            return new Promise((resolve) => {
                resolve(printLater(msg, time));
            });
        }
    

    注意:解决/拒绝承诺始终是最佳做法。

    it('await promise 3.1', async function () {
            /* Prints the following:
            [TRACE] default - Start
            [DEBUG] default - Sleeping for 100 ms...
            [INFO] default - --1
            */
            await logger.trace("Start");
    
            await nativePromise("--1", 100);
            await nativePromise("--2", 200);   // Gets stuck after "--1"
            await nativePromise("--3", 300);
            await logger.info("--done");
    
            await logger.trace("End");
        });
    

    对于前面的代码 sn -p 原因与我之前提到的相同。 await 还等待承诺解决/拒绝。如果它没有返回任何东西,那么 await 也会在某一时刻卡住。

    我们使用 await 来使代码更简洁。在内部它也等待承诺解决/拒绝并且它不返回承诺对象。 await 从 promise 对象中取出值并返回。

    注意1:来自 Jasmine 的期望在执行任何进一步操作之前等待控制流清空refer this link from Protractor

    NOte2:Protractor Promise 实际上是 webdriver.Promise 在 Protractor 和 webdriverJs 中已被弃用。所以如果可能的话不要使用它们。

    【讨论】:

    • 感谢@nitin-sahu 的快速回复!你说得对,我忘了添加解决/拒绝调用。我忘记添加的另一件事是对 Protractor 提供给 it() 的 done() 方法的调用。添加这些修复后,代码工作得更好(请参阅我的 git repo 中的提交 #5),但我仍然不明白为什么 second_spec.ts 中的 expect() 调用没有立即停止测试 - 我在 expect() 之后仍然可以看到打印语句。同样在 first_spec.ts 中,为什么测试 1.1 的一些输出会溢出到测试 1.2,而 2.1 会溢出到 2.2?
    • 好的,我修复了提交 6 中的所有承诺测试。我认为 Javascript 隐式返回函数中的最后一条语句,但看起来我必须为 then() 中的所有承诺显式添加返回语句链。一旦遇到失败的 expect() 语句,它仍然不会立即停止测试,但不幸的是,也许这就是 Jasmine 的工作方式?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多