javascript - 我如何将 expect() 与 Protractor promise 链中的非 Protractor promise 混合使用?

标签 javascript typescript jasmine protractor

我试图了解如何(以什么顺序)在 Protractor 中执行 promise ,特别是对于与 Protractor promise 混合的非 Protractor promise (例如 native 或 q promise )。 我在工作中调试和修复一些不稳定的 Protractor 测试,我绝对不是 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

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

最佳答案

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

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 block 。

    it(' promise 链 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 函数异步工作并记录其结果。

使它与第一个 it block 相同的简单方法是对 nativePromise 函数进行轻微更改。您将必须使用 resolve 来确保此 promise 得到解决。

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

注意:解决/拒绝 promise 始终是最佳实践。

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 。如果它没有返回任何东西,那么 await 也会卡在某一点。

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

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

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

关于javascript - 我如何将 expect() 与 Protractor promise 链中的非 Protractor promise 混合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56641077/

相关文章:

javascript - 说明如何通过 Google 跟踪代码管理器使用 Google Analytics(分析)

javascript - renameFiles - 获取文件名数组并根据它们在数组中出现的次数重命名它们

javascript - 如何 stub img 调用

javascript - 如何在 JavaScript 的正则表达式中包含内联注释

javascript - 在 Firefox 中,设置 checkbox.disabled = false 后 click() 不会立即运行

javascript - 调整窗口大小时更改元素宽度(以 px 为单位)

angular - 如果输入长度小于 3,则禁用按钮

javascript - 类型 'File' 的参数不可分配给类型 'string' 的参数

javascript - Materialise closeModal 未触发完成

Angular 2 在没有模拟的情况下测试具有可观察对象的组件