Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
JSON Schema と 
API テスト 
2014/08/29 (Sat) 
YAPC::Asia Tokyo 2014 
清水 直樹
自己紹介 
• 清水 直樹 (@deme0607) 
• SWET @ DeNA 
• SWET: Software Engineer in Test 
• 2013年 4月 新卒入社
自己紹介② 
• テスト用のライブラリ 
• randexp-multibyte 
• https://rubygems.org/gems/randexp-multibyte 
• Rubyist Magazine 「Ruby 初心者の新卒エン...
今日の話 
• API 結合テストとは? 
• JSON Schema とは? 
• JSON Schema を API 結合テストに活用
API結合テスト
API (単体) テスト 
API 
Server 
Test 
1. テストデータをリクエスト 
として送信 
[request] 
GET api/user 
id: 1 
[response] 
id: 1 
name: deme0607...
それだけで十分? 
• API は様々なコンポーネントと結合して動作 
API 
Server 
User 
API 
Server 
DB 
Load Balancer / Reverse Proxy 
[request] [response...
API結合テスト 
• 実環境で動作しているAPIを実際のクライアン 
トと同じ経路からテスト 
API 
Server 
結合 
テスト 
API 
Server 
DB 
Load Balancer / Reverse Proxy 
[re...
API結合テスト 実施フロー 
• 仕様ドキュメントから、正常系・異常系テストリク 
エストデータを作成 
• リクエストデータ ≒ テストケース 
• 仕様とリクエストデータから、期待するレスポンス 
を定義 
• テスト用クライアントからリ...
今日の話 
• API 結合テストとは? 
• JSON Schema とは? 
• JSON Schema を API 結合テストに活用
JSON Schema とは? 
• JSONで表現されるデータに対してデータ定義 
するSchemaを記述する枠組み 
• json-schema.org で公開されている 
• 現在、draft4
例 
• JSON データ 
! 
• 日本語の仕様 
! 
! 
• JSON Schema 
{ 
"id": 
12345678, 
"name": 
"Naoki 
Shimizu", 
"email": 
"deme0607@exam...
JSON Schema, 何が嬉しい? 
• データの検証にも使える 
• Machine Readable なデータの定義ができるので、Validatorの 
入力にできる 
• 仕様と実装の乖離が減る 
• 上記のようなValidatorを...
• Validator を使ってAPIサーバのリクエスト・レスポンスのSchemaとの整合性を検証 
• perl-JSV: Perlのデータに対する JSON Schema Validator 
• https://github.com/zi...
JSON Schema について詳しくは 
WEB+DB Press vol.82 特集1 「Web API デザインの鉄則」をご覧ください
今日の話 
• API 結合テストとは? 
• JSON Schema とは? 
• JSON Schema を API 結合テストに活用
(再) API結合テスト 実施フロー 
• 仕様ドキュメントから、正常系・異常系テストリク 
エストデータを作成 
• リクエストデータ ≒ テストケース 
• 仕様とリクエストデータから、期待するレスポンス 
を定義 
• テスト用クライアン...
API 仕様が JSON Schema 
で書かれていたら?
• 正常系・異常系のリクエストデータを自動生 
成できるかも? 
• 仕様とリクエストデータから、期待するレス 
ポンスも自動で定義できるかも? 
• 仕様から、クライアントも自動生成できるか 
も?
APIの結合テスト、 
全部自動でできちゃう?
そんなうまい話はありません
だが、今よりもっと楽する 
ことはできるはず
やりたいこと 
• JSON Schema で記述された API の仕様から 
• 正常系・異常系のリクエストデータ生成 
• 期待するレスポンスの定義 
• APIクライアントの生成
json-fuzz-generator 
• JSON Schema から、そのSchemaに対して正常 
系・異常系のデータを生成 
• Ruby のライブラリ 
• 異常系のデータはFuzzingに基いている 
• 誤りの含まれたデータを次...
デモ
正常系データの生成 
# 
require 
"json-­‐fuzz-­‐generator" 
# 
JSON::Fuzz::Generator.default_param(schema_file) 
{ 
"id" 
=> 
0, 
"n...
異常系データの生成 
[ 
["sample", 
"array"], 
true, 
73, 
nil, 
0.34259093948835795, 
"hoge", 
{"id"=>"a", 
"name"=>"hoge", 
"birth...
JSON Schema から自動生成 
したリクエストデータは、 
テストケースとして十分か?
残念ながらNoです
• ドメイン知識に基づくケースは生成できない 
• JSON Schemaではデータのフォーマット以上のこ 
とは定義できない 
• (例) 友達にメッセージを送るAPIで、「友達でない 
ユーザへのメッセージ送信」という異常系リクエス 
ト ...
API結合テスト 自動化への道 
• リクエストデータの生成 
• レスポンスの検証 
• APIクライアントの生成
リクエストデータの生成 
• フォーマットによるもの 
• json-fuzz-generator によって生成できる 
• ドメインの特性によるもの 
• JSON Schema からの生成は不可能
レスポンスの検証 
• フォーマット 
• JSON Schema による Validator で可能 
• perl-JSV (Perl), json-schema (Ruby) 
• APIのロジックに基づくもの 
• 例: リクエストで指...
APIクライアントの自動生成 
• jsonism で生成可能 (Ruby ライブラリ) 
client 
= 
Jsonism::Client.new(schema: 
schema) 
client.methods(false) 
#=> ...
API結合テスト 自動化への道 
リクエスト生成レスポンス検証 
クライアント 
生成 
フォーマットドメイン特性フォーマットロジック 
fuzz-json-generator 
★ perl-JSV 
json-schema ★ jsonis...
まとめ 
• JSON Schema で仕様を記述すると開発でも 
テストでも利点がある 
• JSON Schema を使って、API結合テストの自 
動化に取り組んでいる 
• 自動化が進むと、より高品質な開発・テスト 
に集中できる
ありがとうございました 
• json-fuzz-generator 
• https://rubygems.org/gems/json-fuzz-generator 
• Twitter 
• https://twitter.com/deme...
json-fuzz-generator要改善点 
• 正常系データの複数生成 
• 例: 各種境界値 
• 現状、最大値・最小値が定義されているような数値は範囲内のラン 
ダム値を返すような実装 
• 未対応のschema 
• pattern...
• 異常系パラメータの精度向上 
• Fuzzingでは桁あふれを起こしうる数値や文字化けを起こしやすい文 
字列を入力することが効果的 
• 現状は単純な異常値しか生成してない 
• stringを期待するデータにintegerを出力 
• ...
Próxima SlideShare
Cargando en…5
×

JSON Schema と API テスト YAPC::Asia Tokyo 2014

12.896 visualizaciones

Publicado el

YAPC::Asia Tokyo 2014 Talk
https://www.youtube.com/watch?v=bxNMk6XP2JA

Publicado en: Tecnología
  • Sé el primero en comentar

JSON Schema と API テスト YAPC::Asia Tokyo 2014

  1. 1. JSON Schema と API テスト 2014/08/29 (Sat) YAPC::Asia Tokyo 2014 清水 直樹
  2. 2. 自己紹介 • 清水 直樹 (@deme0607) • SWET @ DeNA • SWET: Software Engineer in Test • 2013年 4月 新卒入社
  3. 3. 自己紹介② • テスト用のライブラリ • randexp-multibyte • https://rubygems.org/gems/randexp-multibyte • Rubyist Magazine 「Ruby 初心者の新卒エンジニアが gem パッケージ公開に至るまで」 • http://magazine.rubyist.net/?0046- RandexMultibyteGem
  4. 4. 今日の話 • API 結合テストとは? • JSON Schema とは? • JSON Schema を API 結合テストに活用
  5. 5. API結合テスト
  6. 6. API (単体) テスト API Server Test 1. テストデータをリクエスト として送信 [request] GET api/user id: 1 [response] id: 1 name: deme0607 email: deme0607@example.com 2. レスポンスデータを期待結果 と比較
  7. 7. それだけで十分? • API は様々なコンポーネントと結合して動作 API Server User API Server DB Load Balancer / Reverse Proxy [request] [response]
  8. 8. API結合テスト • 実環境で動作しているAPIを実際のクライアン トと同じ経路からテスト API Server 結合 テスト API Server DB Load Balancer / Reverse Proxy [request] [response]
  9. 9. API結合テスト 実施フロー • 仕様ドキュメントから、正常系・異常系テストリク エストデータを作成 • リクエストデータ ≒ テストケース • 仕様とリクエストデータから、期待するレスポンス を定義 • テスト用クライアントからリクエストを送り、レス ポンスを検証
  10. 10. 今日の話 • API 結合テストとは? • JSON Schema とは? • JSON Schema を API 結合テストに活用
  11. 11. JSON Schema とは? • JSONで表現されるデータに対してデータ定義 するSchemaを記述する枠組み • json-schema.org で公開されている • 現在、draft4
  12. 12. 例 • JSON データ ! • 日本語の仕様 ! ! • JSON Schema { "id": 12345678, "name": "Naoki Shimizu", "email": "deme0607@example.com" } ! { "type": "object", "properties": { "id": { "type": "integer", "minimum": 10000000 }, "name": { "type": "string" }, "email": { "type": "string", "format": "email" } } } フィールド型詳細 id integer ユーザのidを表す。 10000000以上の値。 name string ユーザの名前を表す文字列。 email string ユーザのメールアドレス。 RFC5322形式の文字列。
  13. 13. JSON Schema, 何が嬉しい? • データの検証にも使える • Machine Readable なデータの定義ができるので、Validatorの 入力にできる • 仕様と実装の乖離が減る • 上記のようなValidatorを活用し、APIのリクエスト・レスポン スを検証 • グローバル対応 • JSONは機械にも人間にも読みやすい
  14. 14. • Validator を使ってAPIサーバのリクエスト・レスポンスのSchemaとの整合性を検証 • perl-JSV: Perlのデータに対する JSON Schema Validator • https://github.com/zigorou/perl-JSV use JSON; use JSV::Validator; my $request = { id => 12345678, name => "Naoki Shimizu", email => "deme0607@example.com", }; my $schema = decode_json($json_file); my $validator = JSV::Validator-­‐>new; my $result = $validator-­‐>validate($schema, $request); if ($result) { ...
  15. 15. JSON Schema について詳しくは WEB+DB Press vol.82 特集1 「Web API デザインの鉄則」をご覧ください
  16. 16. 今日の話 • API 結合テストとは? • JSON Schema とは? • JSON Schema を API 結合テストに活用
  17. 17. (再) API結合テスト 実施フロー • 仕様ドキュメントから、正常系・異常系テストリク エストデータを作成 • リクエストデータ ≒ テストケース • 仕様とリクエストデータから、期待するレスポンス を定義 • テスト用クライアントからリクエストを送り、レス ポンスを検証
  18. 18. API 仕様が JSON Schema で書かれていたら?
  19. 19. • 正常系・異常系のリクエストデータを自動生 成できるかも? • 仕様とリクエストデータから、期待するレス ポンスも自動で定義できるかも? • 仕様から、クライアントも自動生成できるか も?
  20. 20. APIの結合テスト、 全部自動でできちゃう?
  21. 21. そんなうまい話はありません
  22. 22. だが、今よりもっと楽する ことはできるはず
  23. 23. やりたいこと • JSON Schema で記述された API の仕様から • 正常系・異常系のリクエストデータ生成 • 期待するレスポンスの定義 • APIクライアントの生成
  24. 24. json-fuzz-generator • JSON Schema から、そのSchemaに対して正常 系・異常系のデータを生成 • Ruby のライブラリ • 異常系のデータはFuzzingに基いている • 誤りの含まれたデータを次々に入力するテスト 手法
  25. 25. デモ
  26. 26. 正常系データの生成 # require "json-­‐fuzz-­‐generator" # JSON::Fuzz::Generator.default_param(schema_file) { "id" => 0, "name" => "hoge", "birthday” => "1992-­‐06-­‐27" } JSON Schema の入力 ! { "title": "Basic Schema", "type": "object", "properties": { "id" : { "type": "integer", "minimum": 0 }, "name": { "type": "string" }, "birthday": { "type": "string", "format": "date" } } } 正常系データの出力
  27. 27. 異常系データの生成 [ ["sample", "array"], true, 73, nil, 0.34259093948835795, "hoge", {"id"=>"a", "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>"1", "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0.1, "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>["sample", "array"], "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>false, "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>nil, "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0.0, "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>{}, "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>"hoge", "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>-­‐1, "name"=>"hoge", "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0, "name"=>["sample", "array"], “birthday"=>"1992-­‐06-­‐27"}, ! {"id"=>0, "name"=>true, "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0, "name"=>97, "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0, "name"=>nil, "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0, "name"=>0.7547537108664406, "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0, "name"=>{}, "birthday"=>"1992-­‐06-­‐27"}, {"id"=>0, "name"=>"hoge", "birthday"=>["sample", "array"]}, {"id"=>0, "name"=>"hoge", "birthday"=>false}, {"id"=>0, "name"=>"hoge", "birthday"=>11}, {"id"=>0, "name"=>"hoge", "birthday"=>nil}, {"id"=>0, "name"=>"hoge", "birthday"=>0.5380909041403419}, {"id"=>0, "name"=>"hoge", "birthday"=>{}}, {"id"=>0, "name"=>"hoge", "birthday"=>"2010-­‐01-­‐32"}, {"id"=>0, "name"=>"hoge", "birthday"=>"n2010-­‐01-­‐01"}, {"id"=>0, "name"=>"hoge", "birthday"=>"2010-­‐1-­‐01"}, {"id"=>0, "name"=>"hoge", "birthday"=>"2010-­‐01-­‐1"}, {"id"=>0, "name"=>"hoge", "birthday"=>"2010-­‐01-­‐01n"}, ]
  28. 28. JSON Schema から自動生成 したリクエストデータは、 テストケースとして十分か?
  29. 29. 残念ながらNoです
  30. 30. • ドメイン知識に基づくケースは生成できない • JSON Schemaではデータのフォーマット以上のこ とは定義できない • (例) 友達にメッセージを送るAPIで、「友達でない ユーザへのメッセージ送信」という異常系リクエス ト • ドメイン知識が必要なケースの設計に集中できる
  31. 31. API結合テスト 自動化への道 • リクエストデータの生成 • レスポンスの検証 • APIクライアントの生成
  32. 32. リクエストデータの生成 • フォーマットによるもの • json-fuzz-generator によって生成できる • ドメインの特性によるもの • JSON Schema からの生成は不可能
  33. 33. レスポンスの検証 • フォーマット • JSON Schema による Validator で可能 • perl-JSV (Perl), json-schema (Ruby) • APIのロジックに基づくもの • 例: リクエストで指定したユーザidのデータが返ってくる • JSON Schema からは不可能
  34. 34. APIクライアントの自動生成 • jsonism で生成可能 (Ruby ライブラリ) client = Jsonism::Client.new(schema: schema) client.methods(false) #=> [:create_app, :delete_app, :info_app, :list_app, :update_app] # GET /apps client.list_app # GET /apps/1 client.info_app(id: 1) # POST /apps client.create_app(name: "alpha") # PATCH /apps/1 client.update_app(id: 1, name: "bravo") # DELETE /apps/1 client.delete_app(id: 1)
  35. 35. API結合テスト 自動化への道 リクエスト生成レスポンス検証 クライアント 生成 フォーマットドメイン特性フォーマットロジック fuzz-json-generator ★ perl-JSV json-schema ★ jsonism ドメイン知識やロジック部分に集中したテスト設計が可能
  36. 36. まとめ • JSON Schema で仕様を記述すると開発でも テストでも利点がある • JSON Schema を使って、API結合テストの自 動化に取り組んでいる • 自動化が進むと、より高品質な開発・テスト に集中できる
  37. 37. ありがとうございました • json-fuzz-generator • https://rubygems.org/gems/json-fuzz-generator • Twitter • https://twitter.com/deme0607
  38. 38. json-fuzz-generator要改善点 • 正常系データの複数生成 • 例: 各種境界値 • 現状、最大値・最小値が定義されているような数値は範囲内のラン ダム値を返すような実装 • 未対応のschema • pattern (正規表現) • patternにマッチする/しない文字列を自動生成 • $ref (参照) 系
  39. 39. • 異常系パラメータの精度向上 • Fuzzingでは桁あふれを起こしうる数値や文字化けを起こしやすい文 字列を入力することが効果的 • 現状は単純な異常値しか生成してない • stringを期待するデータにintegerを出力 • 最大値・最小値の範囲から外れる値を出力 • プロダクトに基づくパラメータの生成 • 過去にバリデーション漏れ・問題を起こしたパラメータなど • ライブラリに同梱するのではなく、ユーザが動的に追加できる仕組 み

×