npm npm Build Status Coverage Status Known Vulnerabilities style NPM

api-contract-validator

此斷言函式庫的外掛程式,用於根據 Swagger/OpenAPI 定義驗證 API 回應的結構描述。

使用此外掛程式很簡單。只需將此外掛程式指向您的 API 定義檔路徑,並在您的整合測試中新增一行,以驗證您的應用程式是否符合其設計契約。

重點

  • 根據 API 定義文件進行斷言
  • 描述性的斷言失敗訊息
  • 簡單且簡潔的用法
  • 涵蓋率報告(可以列印到您的終端機或匯出到 json 檔案)
  • 支援來自 axiossuperagentsupertestrequestlight-my-request(由 fastify 使用)的回應格式
  • 支援 OpenAPI 3.0
  • 支援多個定義檔案

它是如何運作的?

api-contract-validator 會根據提供的 API 文件,將您的 API 定義轉換為基於 json-schema 的結構描述。然後,每當呼叫 matchApiSchema 斷言時,它會自動從您調用的 API 請求返回的回應物件中提取方法、路徑和狀態碼,並驗證回應物件。回應標頭和主體都會被驗證。

如何使用?

安裝

> npm i --save-dev api-contract-validator

Chai.js

const matchApiSchema = require('api-contract-validator').chaiPlugin;
const path = require('path');
const { expect, use } = require('chai');

// API definitions path
const apiDefinitionsPath = path.join(__dirname, 'myApp.yaml'); 

// add as chai plugin
use(matchApiSchema({ apiDefinitionsPath }));

it('GET /pets/123', async () => {
    const response = await request.get('/pet/123');
    expect(response).to.have.status(200).and.to.matchApiSchema();

    // alternatively pass
    const { statusCode, headers, body } = response
    expect({
        path: '/pet/123',
        method: 'get',
        status: statusCode,
        body: body,
        headers: headers,
    }).to.have.status(200).and.to.matchApiSchema();
})

Should.js

const matchApiSchema = require('api-contract-validator').shouldPlugin;

// API definitions path
const apiDefinitionsPath = path.join(__dirname, 'myApp.yaml');

// add as should plugin
matchApiSchema(should, { apiDefinitionsPath });

it('GET /pets/123', async () => {
    const response = await request.get('/pet/123');
    should(response).have.status(200).and.matchApiSchema();
})

Jest

const matchApiSchema = require('api-contract-validator').jestPlugin;

// API definitions path
const apiDefinitionsPath = path.join(__dirname, 'myApp.yaml');

// add as jest plugin
matchApiSchema({ apiDefinitionsPath });

it('GET /pets/123', async () => {
    const response = await request.get('/pet/123');
    expect(response).toHaveStatus(200);
    expect(response).toMatchApiSchema();
})

多個 API 定義檔

使用帶有檔案路徑陣列的 apiDefinitionsPath 選項

const apiDefinitionsPath = [path.join(__dirname, 'myApp.yaml'), path.join(__dirname, 'myApp2.yaml')];

描述性的斷言失敗訊息

AssertionError: expected response to match API schema
+ expected - actual

{
    "body": {
-    "age": -1
+    "age": "should be >= 0"
+    "name": "should have required property"
    }
    "headers": {
-    "x-expires-after": []
-    "x-rate-limit": -5
+    "x-expires-after": "should be string"
+    "x-rate-limit": "should be >= 0"
    }
}

涵蓋率報告

在此外掛程式選項中提供標誌 reportCoverage:true,此外掛程式會產生所有未涵蓋的 API 定義報告。

use(matchApiSchema({
    apiDefinitionsPath,
    reportCoverage: true
}));
* API definitions coverage report *

Uncovered API definitions found:
*ROUTE*                    | *METHOD*   | *STATUSES* 
/v2/pet                    | POST       | 405        
/v2/pet                    | PUT        | 400,404,405
/v2/pet/findByStatus       | GET        | 200,400    
/v2/pet/findByTags         | GET        | 200,400    
/v2/pet/:petId             | GET        | 400,404    
/v2/pet/:petId             | POST       | 405        
/v2/pet/:petId             | DELETE     | 400,404    
/v2/pet/:petId/uploadImage | POST       | 200         

匯出報告

當提供 exportCoverage: true 時,將會在您的 cwd 中建立一個 coverage.json 檔案,其結構如下

use(matchApiSchema({
    apiDefinitionsPath,
    exportCoverage: true
}));

coverage.json

[{"route":"/v2/pet","method":"POST","statuses":"405"},
{"route":"/v2/pet","method":"PUT","statuses":"400,404,405"},
{"route":"/v2/pet/:petId","method":"GET","statuses":"200"},
{"route":"/v2/pet/:petId","method":"POST","statuses":"405"},
{"route":"/v2/pet/:petId","method":"DELETE","statuses":"404"}]

支援的請求函式庫

  • supertest
  • axios
  • request-promise*
  • 更多即將推出

* 使用 request-promise 時,必須將 resolveWithFullResponse:true 新增至請求選項,才能正確提取請求詳細資訊

支援的斷言函式庫

  • chai.js
  • should.js
  • jest
  • 更多即將推出