簡體   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