会社のRailsプロジェクトで初見のgemに出くわし、便利だったので書きます。
基本的には公式ドキュメントを参考に書いています。
概要
概要を先にまとめると、Committee で、Specを書く際、API設計をしているopenapiドキュメントの内容に沿った、出力がされているかテストすることができる。
Committee::Rails でrails内でCommitteeの利用を可能にする。
実際にはこの二つの組み合わせによって、assert_schema_conformというメソッドが使用可能になり、それをテスト内で使用できるというもの。
テストで期待するいちいち出力の形を定義しなくていいので便利。
それぞれcommittee、committee-railsというGemで利用する。
Committeeとは
JSON Schema, OpenAPI 2, OpenAPI 3.を使って、サービス立ち上げをサポートするための複数のミドルウェアが集まったもの
サポートしているRubyのバージョンは以下。
* 2.3
* 2.4
* 2.5
* 2.6
ミドルウェアの集合体であるため、それぞれのミドルウェアで機能を持つ。
その中で今回はTest Assertionsという便利な機能についてまとめた。
Test Assertionsとは
Committee::Middleware::ResponseValidationに含まれている一つの機能。
Test AssertionsもCommitteeに付随している、ract.testと併用するように設計された少数のスキーマ用のテストアサーション。
HyperSchema とOpenAPI 3 に対応している。
Committee::Middleware::ResponseValidation自体はHyper-SchemaとOpenAPI 2、OpenAPI 対応。
下記のように使う。
describe Committee::Middleware::Stub do
include Committee::Test::Methods
include Rack::Test::Methods
def app
Sinatra.new do
get "/" do
content_type :json
JSON.generate({ "foo" => "bar" })
end
end
end
def committee_options
@committee_options ||= { schema: Committee::Drivers::load_from_file('docs/schema.json'), prefix: "/v1", validate_success_only: true }
end
describe "GET /" do
it "conforms to schema" do
assert_schema_conform
end
end
end
Load_form_fileの後に参照したい、JSON Schema, OpenAPI 2, OpenAPI 3.のいずれかで書かれているファイルのパス、prefixでURLを指定する。
validate_success_onlyは、200系 レスポンスでない場合のみバリデーションをするか否かを指定する。
あとはexample内(it内)でassert_schema_conformを呼ぶだけでOK。
Committee::Railsとは
上記の通り、Committee提供される機能を railsで使えるようにするために存在している。
下記のように使う。
describe 'request spec' do
include Committee::Rails::Test::Methods
def committee_options
@committee_options ||= { schema_path: Rails.root.join('schema', 'schema.json').to_s }
end
describe 'GET /' do
it 'conform json schema' do
get '/'
assert_schema_conform
end
end
end
Committeeで定義されているcommittee_optionsを、Committee::Railsでオーバーライドしている模様。
Rspecの場合はRails 内のrails_helper.rbに上記の内容を書いて、
Specのexample内でassert_schema_conformを使うだけで良さそう。
RSpec.configure do |config|
config.add_setting :committee_options
config.committee_options = { schema_path: Rails.root.join('schema', 'schema.json').to_s }
end
やっぱRspec使った方いい。