PostMan Global Function Pre-request Script

PostMan - 如何使用Global Function(利用 API Tests為例來設定Token)

郭駿佑 2020/09/10 23:01:53
3991

前言

在開發API的時候,PostMan可以說是一項必不可少的工具,如今在軟體的不斷更新之下,已經有了Test與Pre-request Script這些方便使用的功能,在網上也能找到相關的教學。

有一天我在使用PostMan時想到,如果有一個function是每隻API都必須預先呼叫的(例如取得一個六位數隨機驗證碼或者是Token的function)該怎麼辦呢?於是就有了使用Global Function的念頭。

情境

假設有一系列的API,在使用前都必須先呼叫取得Token的API,這時候我們可以土法煉鋼的在每隻API之前先打取得Token的API,或者是在每一支的API利用Pre-request Script或者是Tests來預先取得Token,但是如果之後有需要更動的地方,是不是很不方便呢?這時候如果有Global Function來統一做修改就很方便了。

1.手動取得Token

首先先呼叫取得Token的API

然後把Token填入Authorization內做驗證。

這樣是最基本的呼叫API方式,但是人工填入的方式不僅麻煩,輸入錯誤的風險也提高。於是便有了第二種方法:Pre-scripts。

2.使用Pre-request Script搭配Environment自動填入Token

這邊我利用postman的sendRequest搭配environment的get與set來完成。

pm.sendRequest({
    url: pm.environment.get("url") + '/api/signin',
    method: 'POST',
    header: {
        'Content-Type': 'application/json; charset=utf-8',
        'Content-Encoding': 'gzip',
        'Vary': 'Accept-Encoding',
        'Server': 'Microsoft-IIS/10.0',
        'X-Powered-By': 'ASP.NET',
        'APP_ID': pm.environment.get("APP_ID"),
        'APP_VERSION': pm.environment.get("APP_VERSION")
    },
    body: {
        mode: 'raw',
        raw: JSON.stringify({ account: pm.environment.get("account"), password: pm.environment.get("password") })
    }
}, function (err, response) {
    const jsonResponse = response.json();
    pm.environment.set("signin_token", jsonResponse.token_type + " " + jsonResponse.access_token);
    pm.environment.set("access_token", jsonResponse.access_token);
    pm.environment.set("refresh_token", jsonResponse.refresh_token);
});

然後在environment中新增相關變數。

然後再利用這個token來做驗證。

我們Send request之後,可以發現相關的參數都已經填入。

而send的結果也成功。

這邊使用Pre-request Script自動填入後,的確改善了人工填入的麻煩與風險,但是如果有多個API在使用前都必須呼叫Token這支API時該怎麼辦呢?直覺的想法就是會在每一隻需要的API上都加上呼叫的Pre-request Script,但是這樣就違反了我們Duplicate code的原則。屆時若呼叫Token的API有需要修改時,那會多了很多不必要的麻煩。於是就有了第三種:Pre-request Script搭配Global Function使用。

3.使用Pre-request Script搭配Global Function自動填入多個API內的Token

這邊我是利用Postman的Globals,新增一個VARIABLE,裡面寫著Pre-request Script的功能,再利用Postman的eval來呼叫此script。雖說eval是目前不推薦的呼叫方式,但查了相關文章後,很遺憾地目前Postman似乎只能使用此方法來使用Global Function。

// ======== 取得 Token =======
pm.globals.set('loadUtils', function loadUtils() {
    let utils = {};
    utils.setToken = function setToken() {
        pm.sendRequest({
            url: pm.environment.get("url") + '/api/signin',
            method: 'POST',
            header: {
                'Content-Type': 'application/json; charset=utf-8',
                'Content-Encoding': 'gzip',
                'Vary': 'Accept-Encoding',
                'Server': 'Microsoft-IIS/10.0',
                'X-Powered-By': 'ASP.NET',
                'APP_ID':pm.environment.get("APP_ID"),
                'APP_VERSION':pm.environment.get("APP_VERSION")
            },
            body: {
                mode: 'raw',
                raw: JSON.stringify({ account: pm.environment.get("account"), password: pm.environment.get("password") })
            }
        }, function (err, response) {
            const jsonResponse = response.json();
            pm.test("Token: Status code is 200", function () {
                pm.response.to.have.status(200);
            });
            pm.environment.set("signin_token", jsonResponse.token_type + " " + jsonResponse.access_token);
            pm.environment.set("access_token", jsonResponse.access_token);
            pm.environment.set("refresh_token", jsonResponse.refresh_token);
        });
    };
    return utils;
} + '; loadUtils();');

tests['Utils initialized'] = true;

我們先在取得Token的API的Tests內貼上上方的程式碼,然後再對其執行測試,確定是否有初始化成功。

接著我們可以看到Global的Variable內,已經存入了相關function。此時便已經完成Global Function的撰寫。

呼叫方式則是在你需要的API的Pre-request Script中,使用eval來呼叫即可。

const utils = eval(globals.loadUtils);
utils.setToken();

可以看到相關變數有確實填入。

其他支API也是短短兩行程式碼便可以成功呼叫TOKEN的API並自動填入。

 

如果說驗證TOKEN的這支API,突然需要更改一些參數(例如說Header可能需要多加一些參數),這時候直接在loadUtils內做修改即可,便可以避免Duplicate Code而導致沒改好的風險。

郭駿佑