はじめに
RSpecを利用して、最低限のAPIレスポンステストをしたい!という方に向けて書いてみました。
細かい部分のテストは置いておいて、とにかく 定義通りのレスポンスが得られているかどうか
のみのテストを簡単に行う方法について書いてます。
Swagger2.0形式でのテストに関しては、多くの記事や専用のgemが見つかる中、OpenAPI3.0形式でのドキュメントでテストを行う方法に対する記載があまりなかったので、備忘録もかねて記事にしました。
この記事を読んでできるようになること
- APIが、ドキュメント通りの仕様でレスポンスを返すことができているか? を自動テスとできるようになる
下記のようなケースに、いち早くきづけるようになります。
- プログラム修正で他のAPIにも不具合がでた
- 知らない間に定義が変わっていた
前提条件
- Rails 5を利用してAPI開発を行っている
- OpenAPI3.0形式で記載したAPIドキュメントを利用している
- 私はswaggerを利用してドキュメントを記載しています
- できるだけコストをかけず、自動テストを書きたい!と思っている
下準備
RSpecでのテストにあたり、下記の2つのgemを利用します。
-
json-schema
- JSONオブジェクトのValidateを行うためのgem
- これがなきゃ始まらないぐらい便利なので、是非いれましょう
-
rspec-request_describer
- request specをシンプルに記載できるようになるgem
- 正直なくてもRSpecはかけるが、テストコードの可読性や記述量が圧倒的に違うので可能であれば入れたい
- 本記事では、このgemを利用していることを前提でサンプルコードを記載しています
テストでしか利用しない場合は、下記のようにGemFileに記載し、bundle installをすればOK
group :test do
gem "json-schema"
gem "rspec-request_describer"
end
テストコードを書く
request specになるため、今回はspec/requestsディレクトリの下にテストコードを記載していきます。
/api/users
にアクセスすると、下記のようなレスポンスを返すAPIのテストを書いてみます。
レスポンス
"users": [
{
"id": 1,
"name": "山田太郎"
},
{
"id": 2,
"name": "山田花子"
}
]
テストコード
/spec/requests/user_requst_spec.rb
describe User do
context "ユーザ一覧を取得する" do
let(api_schema) { #OPenAPI3.0で定義したスキーマ情報を取得 }
let(errors){ JSON::Validator.fully_validate(api_schema, request.body, strict: true) }
describe "GET /api/users" do
is_expected.to eq 200 #レスポンスコードの検査
expected(errors).to [] #エラーチェック
end
end
end
簡単な解説
スキーマ情報の取得部分
let(api_schema) { #OPenAPI3.0で定義したスキーマ情報を取得 }
OpenAPI3.0で記載したスキーマ情報を、Hashに変換しておく。
下記のような感じでとってくると楽かと思います(spec_helperにでも取得メソッドとして切り出しておくと便利)
api_schema = JSON.parse("スキーマファイル").dig("paths", "/api/users", "get", "responses", "200", "content", "application/json", "schema")
レスポンスのバリデーション部分
下記のように記載することで、ドキュメントから精製したスキーマ情報と、レスポンスの結果の検証が可能です。
strict
オプションを有効にすることで、定義とレスポンスの項目の過不足があった場合でもエラーと判定するようにしてます。
検査の結果、エラーがある場合は、配列にエラーメッセージが返却されるため、RSpec内で空配列[]
と比較してます。
JSON::Validator.fully_validate(api_schema, request.body, strict: true)
まとめ
以上で
- レスポンスが200であること
- レスポンスBodyがOpenAPI3.0で定義した定義通りになっていること
のテストができるようになりました。
API仕様というのは比較的変わりやすく、その都度テストが必要になってくると思います(特に設計初期段階では)
上記のテストを1つ書いておくと、最低限の品質
は担保できるようになると思います。
この程度のコストで貴族的に自動テスとを行えるようになるのであれば、長く続く開発プロジェクトなどには非常に有効なのではないかと考えてます。
また、今回はレスポンスの検証のために利用しましたが、リクエストの検証にも利用できるので、APIでのリクエスト受付時に必ず通すValidationとして実装することもできます。
今回、いろいろ探したもののあまり情報がなく、ちょっと困ったので記事にしてみました。
おわりに
私自身、本記事の内容のテストを書くために、今更ながらRSpecをもう一度勉強しなおした人間です。
より良い方法などがありましたら、是非ご意見いただけるとありがたいです。