繁体   English   中英

如何在 Postman 测试中使用 Promises?

[英]How to use Promises in Postman tests?

我需要在 Postman 测试中使用一些异步代码。

由于这是一个复杂的场景,我使用以下代码在一个非常简单的测试中重现了该场景:

let promiseNumber = 0;

function resolvedPromise() {
    return new Promise((resolve, reject) => {
        pm.sendRequest('https://postman-echo.com/get', (err, res) => {
            if (err) {
                console.log(err);
                reject();
            } else {
                console.log(`Resolved promise ${++promiseNumber}`);
                resolve();
            }
        });
    });
}

resolvedPromise()
    .then(resolvedPromise)
    .then(resolvedPromise)
    .catch(err => console.log(err));

控制台上的预期结果是:

Resolved promise 1
Resolved promise 2
Resolved promise 3

但相反,我收到:

Resolved promise 1

有没有办法在 Postman 上提供 Promise 或异步代码?

更新:原始解决方案使用 2147483647 作为超时值,现在按照评论中的建议重构为使用 Number.MAX_SAFE_INTEGER。

我做了一些更多的测试,并意识到在我使用 pm.sendRequest 后它总是停止工作。 如果我尝试解决 Promise,它会起作用。

这个线程似乎是一个已知的错误。

它的解决方法是在处理代码时只留下一个开放的超时。 只需确保所有可能的路径清除超时,否则呼叫将挂起 300000 年 😀

// This timeout ensure that postman will not close the connection before completing async tasks.
//  - it must be cleared once all tasks are completed or it will hang
const interval = setTimeout(() => {}, Number.MAX_SAFE_INTEGER);

let promiseNumber = 0;

function resolvedPromise() {
    return new Promise((resolve, reject) => {
        pm.sendRequest('https://postman-echo.com/get', (err, res) => {
            if (err) {
                console.log(err);
                reject();
            } else {
                console.log(`Resolved promise ${++promiseNumber}`);
                resolve();
            }
        });
    });
}

resolvedPromise()
    .then(resolvedPromise)
    .then(resolvedPromise)
    .then(() => clearTimeout(interval))
    .catch(err => {
        console.log(err);
        clearTimeout(interval);
    });

现在它打印出预期的结果:

Resolved promise 1
Resolved promise 2
Resolved promise 3

除了 Felipe 的回答,我还想多分享一点我使用 Postman 的经验。

由于我需要从pm.sendRequest的响应中提取一些值并将它们用于进行主要调用(例如查询字符串)和/或在测试部分中,我在预请求脚本部分运行脚本并设置值在 Postman 环境变量中。

我发现的一个重要点是我必须在clearTimeout(timeout)之前放置所有设置变量的代码(例如pm.environment.set(k, v) clearTimeout(timeout) 否则,如果我pm.environment.set(k, v)做, pm.environment.set(k, v)代码仍将运行,但不会更新环境变量的值。


以下是 Postman v8.5.1的示例。

主叫

期望从环境变量中获得TEST

GET http://google.com/{{TEST}}

预请求脚本

期望设置TEST环境变量,其值来自多个API的结果。 在这个例子中,我只使用从Promise.all返回的最后一个值。

// make sure you do NOT use Number.MAX_SAFE_INTEGER !!
const timeout = setTimeout(() => {}, 100000);

const promise = () => {
    return new Promise((resolve, reject) => {
        console.log('Calling');
        pm.sendRequest('https://jsonplaceholder.typicode.com/todos/' + _.random(1, 100), (err, res) => {
            console.log('run');
            if (err) {
                reject();
            } else {
                resolve(res.json());
            }
        });
    });
}

Promise.all([
    promise(),
    promise(),
    promise(),
    promise(),
    promise(),
    promise(),
    promise(),
    promise(),
]).then(values => {
    console.log('All done');
    const exampleValue = values[values.length-1].id;
    console.log("Last ID: " + exampleValue);

    clearTimeout(timeout);

    // move this line before clearTimeout to fix TEST being undefined
    pm.environment.set("TEST", exampleValue);
});

测试

期望打印TEST环境变量。

// you get undefined if pm.environment.set is run after clearTimeout
// you get correct value if pm.environment.set is run before clearTimeout
console.log(pm.variables.get("TEST"));

如何测试

将 URL 和所有脚本复制到 Postman 后,打开Console并单击Send 查看被调用的实际 URL 的查询字符串(即GET http://google.com/%7B%7BTEST%7D%7D )。 然后重新排列注释中提到的代码,然后再次单击发送 这次一切都应该按预期工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM