[英]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.