Postman實現數字簽名,Session依賴, 接口依賴, 異步接口結果輪詢

Script(JS)爲Postman賦予無限可能

基於Postman 6.1.4 Mac Native版 演示結合user_api_demo實現git

PS 最近接到任務, 要把幾種基本下單接口調試和持續集成一下, 作個常規功能驗證, 研究了下發現, 不一樣的下單途徑, 有的須要登陸(Session依賴), 有的須要驗籤(使用數字簽名的微服務), 接口中依賴不少動態數據, 如用戶id, 地址id, 工單id, 當前時間等等, 並且最重要的一點, 下單接口是異步的, 只返回事件流event_key, 特別在測試環境上, 訂單處理比較慢, 須要對結果進行一個較長時間的輪詢, 在選型時候, 最開始以爲, 異步接口結果輪詢只能用Jmeter的定時器實現, 然而我的實在不太習慣Jmeter的元件組織邏輯(拆分過碎). 遂嘗試用JS + Postman進行實現.github

可行性 新版Postman 增長了Pre-request Script和Test, 使用Javascript, 而且支持Collection(測試集合)/Folder(子測試集) 級別(以下圖), 功能相似與其餘測框架的setUp和tearDown, 至關於具備了Fixtures功能, 能夠針對不一樣的Scope(範圍)來進行準備和斷言及清理. Collection(測試集合)設置算法

Folder(子測試集)設置, 比Collection少個Variables(變量)設置

Postman支持的JS腳本庫json

  • Lodash: 一套JS實用的方法庫, 封裝了不少String, Array, Object等的處理方法, 我的不太經常使用
  • cheerio: 一個Jquery的核心庫, 能夠方便的使用Jquery的方式獲取/斷言Html/XML中的數據
  • tv4 JSON Schema validator: 簡稱tv4, 先定義一個Schema(格式模板), 再驗證你的JSON是否知足這種格式, 可用於斷言JSON類型響應的總體格式是否正確.
  • CryptoJS: 加密庫, 支持AES, DES, HMAC, MD5, SHA1等經常使用加密方式, 可用於生成加密數據或實現生成簽名數據
  • xml2json/json2xml: xml與json格式互轉

[Postman Sandbox Api參考] (https://www.getpostman.com/docs/v6/postman/scripts/postman_sandbox_api_reference)api

同時, Postman的腳本中能夠讀取, 設置變量, 環境變量, 全局變量, 能夠讀取request對象(只讀)和response對象(只讀)的信息, 另外, 重要的是Postman的腳本中也能夠組裝發送接口請求(能夠實現接口依賴/接口結果驗證問題)微信

數字簽名的實現

實現原理: 請求中埋好參數{{sign}}->Pre-request Script生成sign, 並設置環境變量-> 發送請求 通常的延籤接口都是開發給打好jar包扔給你, 本身使用Java或Jmeter調用就行, 可是, 有代碼素養的測試能夠本身實現簽名, 這樣能夠更靈活.app

首先, 作一下參數化, 埋一下變量, 環境中設置了appsercret的環境變量共加密腳本使用 參數化簽名sign框架

用js實現簽名算法異步

簽名算法請參考user_api_demo中delUser接口文檔微服務

Pre-request Script

// 鏈接參數
function con_params(params){
    if(typeof(params) == "string")
        return params;
    else {
        var sort_keys = Object.keys(params).sort();
        var s = '';
        for(var i in sort_keys) {
            var k = sort_keys[i];
            s += k + "=" + con_params(params[k]) + "&";
        }
        return s;
    }
}

// 生成簽名
function cal_sign(appsecret,params){
    var s = con_params(params);
    console.log(s + "appsecret=" + appsecret);
    return CryptoJS.MD5(s+"appsecret="+appsecret).toString();
    
}

var appsecret= pm.environment.get("appsecret");  // 從環境變量中獲取appsecret
params = JSON.parse(request.data);  // 獲取請求數據
delete params.sign;                 // 去掉sign, 獲得元素請求參數
sign = cal_sign(appsecret, params); // 計算簽名

pm.environment.set("sign", sign);   // 添加爲環境變量sign

用js實現簽名算法

Session依賴/ 接口依賴(關聯)

實現原理: Session依賴: 在Pre-request Script請求登陸接口, 再發送請求時會保持Session 接口依賴: 在Pre-request Script請求依賴接口, 從接口相應中拿到須要的參數->設置爲環境變量-> 請求中使用動態參數

Session依賴(須要登陸) 在須要登陸的接口的Pre-request Script中添加發送登陸請求腳本:

base_url = pm.environment.get("base_url");

// 登陸請求, Postman腳本發送表單類(urlencoded)請求方法(Baidu不到的, 官網也沒有哦!)
const loginRequest = {
    url: base_url + '/api/user/login/',
    method: "POST",
    body: {
        mode: 'urlencoded',
        urlencoded: 'name=張三&password=123456'
    }
};
pm.sendRequest(loginRequest, function (err, res) {
    console.log(err ? err : res.text());
});

登陸腳本

接口依賴 接口依賴token, 先在請求中設置動態參數token, 在Pre-request Script中請求getToken接口, 獲取token並設置環境變量 參數化token Pre-request Script

appid = pm.environment.get("appid");
base_url = pm.environment.get("base_url");

pm.sendRequest(base_url+'/api/user/getToken/?appid='+appid, function (err, res) {
    if (err) {
        console.log(err);
    } else {
        token = res.text().split("=")[1];
        pm.environment.set("token", token);
    }
});

提早請求getToken接口並截取到token

異步接口結果輪詢

異步接口驗證是接口測試中的難點之一, 一種是帶獲取結果狀態接口的, 這裏的實現原理是, 發送接口後, 在Test中用JS的setInterval實現輪詢結果

Tests

event_key = pm.response.json().data.event_key; // 從響應中獲取event_key
base_url = pm.environment.get("admin");

// getOrderResult接口
const getOrderResult = {
  url: base_url + '/customer/COrder/getOrderResult',
  method: 'POST',
  body: {
    mode: 'urlencoded',
    urlencoded: 'event_key='+event_key
  }
};

var i = 0; // 計數

// 封裝一個發送請求方法,用於計數器調用
function getResult(){
    pm.sendRequest(getOrderResult, function (err, res) {
        i += 1;
        if(err){
            console.log(err);
        }
        else{
            msg = res.json().data.msg;
            if(msg == 'finish' || i > 10){   // 直到msg字段由working變爲finish, 設置最多輪詢20次, 最多輪詢一分鐘
               clearInterval(timer); 
            }
        }
    });
}

timer = setInterval(getResult, 3000);  // 每s秒請求一次接口獲取結果狀態

輪詢下單結果

更多學習資料請加添加做者微信:lockingfree獲取

相關文章
相關標籤/搜索