JSON解析によるAPIテストという選択肢
JSON解析によるAPIテストという選択肢
はじめに
APIテストを実施する上で、代表的であろうdreddなどのツールを検討してみましたが、LaravelなどのWebフレームワークから呼び出しづらい、APIの通信にセッションを利用しているとテストが難しい、日本語やExampleの資料が少ないなどの困難がありました。
そこで今回は上記の問題を解消するJSON解析によるAPIテストの詳細を備忘録として記載していきたいと思います。
TL;DR
テストツールからAPIリクエスト、レスポンスなどをJSONファイルに吐いて、openapi4j, swagger-parser, json-schemaなどのライブラリを用いることで、OpenAPIと実装したAPIが乖離がないことを検証出来る
JSON解析によるAPIテスト
JSON解析によるAPIテストではAPIサーバーやAPIテストツールの言語やAPIとの通信手段にセッションを利用しているかどうかなどは問題にはなりません。
必要な手順は以下の2点です。
- APIのテスト時にAPIのパスやリクエスト、レスポンスをJSONに出力する
- 出力したJSONをバリデーションツールに渡して検証する
まずは泥臭いですが、テストツールからAPIの情報をファイルに出力します、自分でヘルパーを用意するか、HTTP通信を傍聴するかなどの手段を用います。
大抵のテストツールにはbeforeEach
、afterAll
などのライクサイクルが提供されていますので、それらにフックさせるのがベターかなと思います。
次に出力したJSONをバリデーションツールに渡して検証します。
以下ではswagger-parserとjson-schemaを例にバリデーションを行うサンプルを記載したいと思います。
api.yml
openapi: 3.0.0
info:
title: api
version: '1'
paths:
/person:
post:
summary: Create new person
responses:
'200':
description: OK
operationId: post-person
requestBody:
content:
application/json:
schema:
type: object
properties:
name:
type: string
required:
- name
parameters: []
data.json
検証対象となるデータです。
{
"name": "foo"
}
ValidationSample.java
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import java.nio.file.Files;
import java.nio.file.Path;
class ValidationSample {
public void execute() throws Throwable {
// OpenAPIを読み取る
OpenAPI openAPI = new OpenAPIV3Parser().readLocation("/api.yml", null, null).getOpenAPI();
// APIテストの際に出力されたJSONデータを読み取る
String data = String.join("", Files.readAllLines(Path.of("/data.json")));
var requestSchema = openAPI.getPaths().get("/person").getPost().getRequestBody().getContent().get("application/json").getSchema();
// スキーマをバリデーションライブラリのモデルにラップする
Schema validator = SchemaLoader.load(new JSONObject(requestSchema));
validator.validate(new JSONObject(data));
}
}
上記のサンプルコードに関してgradleやDockerfileなどの設定ファイルは下記のリポジトリにて公開しています。
最後に
Java、Rubyなどに比べライブラリに貧しいPHPでどうにかOpenAPIによるテストを実現できないか?というのが本記事の背景でした。
しかし、やはり本来的にはcommitteeのように、assert_response_schema
なるアサーションによるテストを記述するべきだと思います…。
Discussion