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