api-contract-validator
このアサーションライブラリのプラグインは、Swagger/OpenAPI 定義に対する API レスポンススキーマを検証するためのものです。
このプラグインの使い方は簡単です。単にプラグインを API 定義ファイルパスにポイントし、アプリケーションが設計契約に従っていることを検証するために統合テストに 1 行追加します。
ハイライト
- API 定義文書に従ってアサートします
- 記述的なアサーションの失敗
- 簡潔で直感的な使用
- カバレッジレポート(ターミナルに出力するか JSON ファイルに出力します)
、axios
、superagent
、supertest
、request
(light-my-request
で使用)からのレスポンス形式をサポートしていますfastify
- OpenAPI 3.0 をサポート
- 複数の定義ファイルに対応
仕組み
api-contract-validator は、API 定義文書から JSON スキーマに API 定義を変換します。その後、
アサーションが呼び出されると、起動した API リクエストによって返却されたレスポンスオブジェクトからメソッド、パス、ステータスコードを自動的に抽出し、レスポンスオブジェクトを検証します。レスポンスヘッダーとボディの両方が検証されます。matchApiSchema
使用方法
インストール
> 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"
}
}
カバレッジレポート
プラグインオプションで
フラグを提供することにより、プラグインは、未検出のすべての API 定義のレポートを生成します。reportCoverage:true
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
- その他