我该如何在量角器承诺链中混合,期望和非量角器承诺?

时间:2019-06-18 02:37:47

标签: javascript typescript jasmine protractor

我试图了解如何在量角器中执行承诺(按什么顺序),特别是对于与量角器承诺混合的非量角器承诺(例如本机或q承诺)。 我正在调试和修复一些不稳定的量角器测试,而JavaScript程序员却毫无想象力。因此,在给出答案时,假设您的答案会超出我的脑海,并将其降低一到两个级别。

在使用特殊的易碎测试工作几天后,我决定写一些非常简单的示例来尝试理解promise链是如何执行的。 根据我在网上阅读的内容,我认为这样链接:

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

在所有这些情况下以及使用原生承诺与量角器承诺时,我都得到了不同的结果。 在second_spec.ts中,我还尝试在promise中添加Expect()语句,该语句应该失败,并且我期望在期望()之后链接的promise不会执行,因为期望会引发断言错误,但是我看到的是在执行之后发出诺言,但是由于Expect()失败,测试仍然失败。很奇怪...

1 个答案:

答案 0 :(得分:0)

您的一个问题包含许多子问题,但都很好。因此,最好是一个一个地走,我会尽力向您解释这可能会帮助您解决问题。

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('promise chain 1.1',function(){         / *打印以下内容:         [TRACE]默认-开始         [DEBUG]默认-睡眠100毫秒...         [TRACE]默认-结束         [INFO]默认--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函数可以异步工作并记录其结果。

使其与first it块相同的简单方法是对nativePromise函数进行一些更改。您将必须使用resolve来确保此诺言得以解决。

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");
    });

对于前面的代码段,原因与我之前提到的相同。等待也等待诺言解决/拒绝。如果它没有返回任何东西,那么等待也将停留在某一时刻。

我们使用await来使代码更整洁。在内部,它也等待promise解析/拒绝,并且不返回promise对象。等待从promise对象获取值并返回。

注意1:Jasmine的期望在执行任何进一步的操作refer this link from Protractor

之前等待控制流为空。

注2:Protractor Promise实际上是webdriver.Promise在Protractor和webdriverJs中已弃用。因此,如果可能不要使用它们。