npm npm Build Status Coverage Status Known Vulnerabilities style NPM

api-contract-validator

このアサーションライブラリのプラグインは、Swagger/OpenAPI 定義に対する API レスポンススキーマを検証するためのものです。

このプラグインの使い方は簡単です。単にプラグインを API 定義ファイルパスにポイントし、アプリケーションが設計契約に従っていることを検証するために統合テストに 1 行追加します。

ハイライト

  • API 定義文書に従ってアサートします
  • 記述的なアサーションの失敗
  • 簡潔で直感的な使用
  • カバレッジレポート(ターミナルに出力するか JSON ファイルに出力します)
  • axiossuperagentsupertestrequestlight-my-requestfastify で使用)からのレスポンス形式をサポートしています
  • OpenAPI 3.0 をサポート
  • 複数の定義ファイルに対応

仕組み

api-contract-validator は、API 定義文書から JSON スキーマに API 定義を変換します。その後、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 が提供されると、カレントワーキングディレクトリに次の構造の 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
  • その他