如何在Postman测试中使用Promises?

时间:2018-12-26 16:02:47

标签: javascript asynchronous testing promise postman

我需要在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

邮递员是否可以使用Promises或异步代码?

2 个答案:

答案 0 :(得分:5)

我做了一些测试,意识到使用pm.sendRequest之后它总是停止工作。如果我尝试解决Promise,那就行了。

似乎是一个已知错误,正在查看this thread

它的解决方法是仅在处理代码时保留打开超时。只需确保所有可能的路径清除超时,否则通话将挂起25天

// 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
//  - the number 2147483647 is the maximum value of a 32 bit integer and is something close to 25 days.
const interval = setTimeout(() => {}, 2147483647);

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

答案 1 :(得分:0)

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

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

我发现的一个重要点是我必须将所有设置变量的代码(例如 pm.environment.set(k, v))放在 clearTimeout(timeout) 之前。否则,如果我反过来做,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 后,打开控制台并点击发送。查看被调用的实际 URL 的查询字符串(即 GET http://google.com/%7B%7BTEST%7D%7D)。然后重新排列注释中提到的代码,然后再次点击发送。这次一切都应该按预期进行。