使用 Postman 進行 API 測試的幾個開發小技巧

我們現在經常在專案中大量的使用 Postman 進行 API 測試,不但 API 測試變的非常方便,搭配 Postbot 這套內建的 AI 助理,更能夠大幅提昇 API 測試的開發效率。這篇文章我就來分享幾個撰寫 API 測試的小技巧。

如何使用 Postman 進行 API 測試

我覺得大致上來說,使用 Postman 進行 API 測試的流程,可以分成以下幾個步驟:

  1. 新增 HTTP 要求 (Add request)
  2. 先確認可以順利按下 Send 發出 HTTP 要求
  3. 切換至 Tests 頁籤撰寫測試案例 ( 使用 JavaScript 即可 )
  4. 再次按下 Send 發出 HTTP 要求,並查看測試結果 ( Test Results )

圖示如下:

Postman

一個最簡單的例子如下:

pm.test("response is ok", function () {
    pm.response.to.have.status(200);
});

你可以看到右上角有個 Script with Postbot 功能,按下去之後,輸入一些提示(Prompt),例如 Add tests to this request,他就會全自動產生測試程式碼,這個功能非常方便,可以大幅提昇 API 測試的開發效率!

Postbot

這裡需要特別注意的地方是,你一定要先確認可以順利按下 Send 發出 HTTP 要求,並且得到一些結果,然後才能透過 Postbot 幫你撰寫測試案例。

撰寫測試案例的基本結構

基本上 Postman 中的每一個 HTTP 要求,都可以撰寫一個以上的測試案例,每個測試案例的程式碼結構如下:

pm.test("測試案例名稱", function () {
    // Assertions
});

你也可以用以下程式碼片段,在 pm.test 後面加上 .skip 即可讓這段測試案例跳過執行

pm.test.skip("測試案例名稱", () => {
    // Assertions
});

你也可以有條件的跳過特定幾個測試案例,例如:

const shouldBeSkipped = true; // some condition

(shouldBeSkipped ? pm.test.skip : pm.test)("測試案例名稱", () => {
    // Assertions
});

各種 Assertions 撰寫範例

  • 直接失敗的測試案例

    有時候我們後端開發人員尚未把 API 開發完成,或程式只有骨架而已,尚未實作任何商業邏輯,此時我們其實也可以先寫好一個會報「紅燈」的測試,也就是讓該 API 的測試案例直接失敗,此時你可以這樣寫測試案例程式:

    pm.test('開發完成度', () => {
        pm.expect.fail('API 尚未開發完成');
    });
    

    事實上在執行時,會得到以下結果,訊息非常清楚:

    開發完成度 | AssertionError: API 尚未開發完成
    
  • 測試 HTTP 狀態碼

    驗證 HTTP 狀態碼是否為 200

    pm.response.to.have.status(200);
    

    你也可以這樣寫 (我個人比較喜歡這種統一的撰寫風格)

    pm.expect(pm.response.code).to.equal(200);
    

    驗證 HTTP 狀態碼是否為 201 或 202

    pm.expect(pm.response.code).to.be.oneOf([201,202]);
    

    驗證 HTTP 狀態碼的「文字」部分

    pm.response.to.have.status("Created");
    
  • 測試 HTTP 回應標頭 (Response Headers)

    驗證 HTTP 回應標頭包含了 Cache-Control 標頭

    pm.response.to.have.header('Cache-Control');
    

    驗證 HTTP 回應標頭包含了 Cache-Control 標頭且內容等於 no-cache

    pm.expect(pm.response.headers.get('Cache-Control')).to.eql('no-cache');
    

    驗證 HTTP 回應標頭包含了 Content-Type 標頭且內容等於 application/json

    pm.expect(pm.response.headers.get('Content-Type')).to.eql('application/json');
    

    注意: .to.eq() 等同於用 === 做比較,這意味著 {a: 1} 不會等於 {a: 1} 的。而 .to.eql() 則是採用 deep equal 的方式做比較,可以比較兩個物件,這意味著 {a: 1} 將會等於 {a: 1} 喔!

  • 測試 HTTP 回應 Cookies

    驗證 HTTP 回應標頭包含了 .AspNet.ApplicationCookie Cookie

    pm.expect(pm.cookies.has('.AspNet.ApplicationCookie')).to.be.true;
    

    驗證 HTTP 回應標頭包含了 isLoggedIn Cookie 且內容等於 1

    pm.expect(pm.cookies.get('isLoggedIn')).to.eql('1');
    
  • 測試 HTTP 回應時間 (Response Time)

    驗證 HTTP 回應時間要小於 1000ms

    pm.expect(pm.response.responseTime).to.be.below(1000);
    
  • 測試 HTTP 回應內容 (Response Body)

    驗證 HTTP 回應內容等於 OK

    pm.response.to.have.body("OK");
    

    驗證 HTTP 回應內容包含 新增成功 (這種方式用於無法解析回應格式的狀況)

    pm.expect(pm.response.text()).to.include('新增成功');
    

    驗證 HTTP 回應內容為 JSON 格式

    pm.response.to.have.jsonBody();
    
  • 測試 HTTP 回應內容 (Response Body) - 驗證 JSON 格式

    要對 API 回應的 JSON 內容做出斷言,首先要取得 JSON 物件!

    const jsonData = pm.response.json();
    

    如果回應內容為 XML 的話,可以使用 xml2Json 內建函式將 XML 轉換為 JSON 物件:

    const jsonData = xml2Json(responseBody);
    

    驗證 JSON 結果一定是從一個「物件」開始:

    pm.expect(jsonData).to.be.an('object');
    

    驗證 JSON 結果一定是從一個「陣列」開始:

    pm.expect(jsonData).to.be.an('array');
    

    驗證 JSON 結果的各屬性型別:

    pm.expect(jsonData.name).to.be.a("string");
    pm.expect(jsonData.age).to.be.a("number");
    pm.expect(jsonData.website).to.be.undefined;
    pm.expect(jsonData.email).to.be.null;
    

    注意: to.be.a(type)to.be.an(type) 的第一個參數為型別名稱,例如: stringnumberbooleanobjectarrayfunctionnullundefined 等等。

    驗證 JSON 結果的第 1 層的 url 屬性必須是個「字串」型別,且長度至少為 1 以上:

    pm.expect(jsonData.url).to.be.a('string').and.to.have.lengthOf.at.least(1, "Value should not be empty");
    

    驗證 JSON 結果的第 1 層的 type 屬性必須是清單中的其中一個字串:

    pm.expect(jsonData.type).to.be.oneOf(["Subscriber", "Customer", "User"]);
    

    驗證 JSON 結果的第一層必須包含特定屬性名稱:

    pm.expect(jsonData.count).to.exist;
    pm.expect(jsonData.items).to.exist;
    

    驗證 JSON 結果的第 2 層的 options 屬性必須是個物件,且必須包含特定屬性名稱:

    pm.expect(jsonData.options).to.exist.and.to.be.an('object');
    pm.expect(jsonData.options).to.have.property('foo1');
    pm.expect(jsonData.options).to.have.property('foo2');
    
    pm.expect(jsonData.options).to.have.all.keys('foo1', 'foo2'); // 物件必須找到所有屬性 (完全比對)
    pm.expect(jsonData.options).to.have.any.keys('foo1', 'foo2'); // 物件必須找到任何屬性 (部分比對)
    

使用內建的動態變數 (Dynamic variables)

在 Postman 之中有一些內建的動態變數,可以讓你在測試案例中使用,例如使用 $guid 可以產生一個亂數的 GUID 來用。

不過在 Tests 頁籤中,必須透過 pm.variables.replaceIn() 函式來取得動態變數的值,例如:

var guid = pm.variables.replaceIn('{{$guid}}');

完整的動態變數清單可參考官網的 Dynamic variables 文件。

相關連結

留言評論