Help us understand the problem. What is going on with this article?

PHPUnit + openapi-validator で「スキーマが正、実装が追従」にする

More than 1 year has passed since last update.

PHPUnit + openapi-validator で「スキーマが正、実装が追従」にする

by kon_shou
1 / 16

今回話したいこと

(API開発チームのひとコマ)

:woman: 「『実装が正、スキーマが追従』って無理だよね」

:man_tone2: 「『スキーマが正、実装が追従』するようにしたいよね」

※本記事はLaravel/Vue.js勉強会#10の発表資料です


しましょう

PHPUnitで、APIがスキーマと異なるレスポンスを返したら、落ちるテストを書きましょう :red_circle:


そのために必要なもの

  • OpenApi
  • redoc-cli
  • PHPUnit
  • openapi-validator

OpenApi

スキーマを書くための すごい yaml (JSON)。

まぁまぁ覚えることが多い。

https://swagger.io/docs/specification/about/


こんな感じ

openapi: 3.0.2
info:
  title: 蔵書管理システムAPIドキュメント
  description: 蔵書管理システムのAPIドキュメントです
  version: 1.0.0
servers:
  - url: https://example.com/api
    description: 本番環境
paths:
  /books:
    get:
      summary: 本の一覧
      description: |
        登録してある本の一覧を取得できます
      operationId: getBooks
      parameters:
        - name: borrow
          in: query
          description: |
            貸出中を含める
          required: false
          schema:
            type: boolean
            example: true
      responses:
        200:
          description: 成功
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/book'
components:
  schemas:
    book:
      title: Book
      description: Bookのスキーマです。
      required:
        - id
        - title
        - created_at
        - updated_at
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
      example:
        id: "1"
        title: "Love beautiful code"
        created_at: "2019-07-08 15:22:15"
        updated_at: "2019-07-08 15:22:15"

Q. なんかよくわかんないんだけど…
A. 慣れれば読めるようになります!頑張ってください!!


redoc-cli

さっきのよくわかんない yaml をhtmlにしてくれるやつ

コマンド一発でドキュメントを作ってくれるから便利

redoc-cli bundle ./resources/docs/apiV1.yml -o ~/book_sample.html

https://github.com/Redocly/redoc/tree/master/cli


こんな感じ
Screenshot from 2019-07-16 23-16-25.png


openapi-validator

OpenApi の yaml をPHPUnitに取りこむやつ

[イメージ図]

response => Validator = (OK) => Green
                      = (NG) => Red

https://gitlab.com/mmalawski/openapi-validator


実装してみる

(Laravelを使う前提)

  1. OpenApi でスキーマを書く
  2. PHPUnit (openapi-validator) でそのスキーマを呼び出す
  3. レスポンスとスキーマが違ってたらRED

1. OpenApi でスキーマを書く

頑張りましょう!

(ドキュメント見つつ悪戦苦闘するしか無いような気が… :innocent: )

https://swagger.io/docs/specification/about

今回は出来上がったスキーマは resources/docs/apiV1.yml に置きます


2. PHPUnit (openapi-validator) でそのスキーマを呼び出す

こんな感じです

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Mmal\OpenapiValidator\Validator;
use Symfony\Component\Yaml\Yaml;


class ApiV1Test extends TestCase
{
    /** @var Validator */
    static $openApiValidator;

    public static function setUpBeforeClass()
    {
        parent::setUpBeforeClass();
        self::$openApiValidator = new Validator(Yaml::parse(file_get_contents(resource_path('docs/apiV1.yml'))));
    }

    /**
     * @test
     */
    public function getBooks()
    {
        $response = $this->get('api/book');

        $result = self::$openApiValidator->validate('getBooks', 200, json_decode($response->getContent(), true));
        $this->assertFalse($result->hasErrors(), $result);
    }
}
  1. テスト前に $openApiValidator としてOpenApiを読み込んで
  2. テストで「OpenApi上のレスポンスの定義 / 期待するステータスコード /レスポンス」を $openApiValidator を渡す
  3. Green or Red

実際にやってみる(Red)

レスポンスから updated_at を消してみると…

Screenshot from 2019-07-16 23-01-19.png

あるはずのプロパティが無いと怒られる!Red!!


実際にやってみる(Green)

レスポンスに updated_at を追加してみると…

Screenshot from 2019-07-16 22-59-17.png

レスポンスとスキーマの定義が同じ!Green!!


テストが全部通った後に

redoc-cli でスキーマを html にして公開!


最後に

何が辛いって、OpenApi(yaml)書くのがとにかく辛いです (^o^)

既存でAPIがあるとなおさらしんどいです (^o^)(^o^)

kon_shou
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away