$30 off During Our Annual Pro Sale. View Details »

RSpecによるOpen API自動テスト

fuqda
August 26, 2020

RSpecによるOpen API自動テスト

【オンライン開催】hey × Da Vinci Studio
〜プロダクトの成長を支えている裏側(技術と組織)〜の発表資料です。
https://hey.connpass.com/event/181259

fuqda

August 26, 2020
Tweet

More Decks by fuqda

Other Decks in Programming

Transcript

  1. RSpecʹΑΔ
    Open APIࣗಈςετ
    ~STORESͷݱ৔͔Β~
    hey × Da Vinci Studio
    ʙϓϩμΫτͷ੒௕Λࢧ͍͑ͯΔཪଆʢٕज़ͱ૊৫ʣʙ
    2020.08.27 @fuqda90

    View Slide

  2. About me fuqda (;ͩ͘)
    • 2017೥11݄ʙݱࡏ
    STORESόοΫΤϯυΤϯδχΞ (Ruby)
    • 2018೥2݄ʙݱࡏ
    Tama.rbͱ͍͏஍ҬRubyίϛϡχςΟ΍ͬͯ·͢
    • झຯ͸ΪλʔͰ͢(ίϩφ͕མͪண͍ͨΒόϯυ׆ಈ͍ͨ͠)
    Twitter : ˏfuqda90

    View Slide

  3. ࠓճ͓࿩͢Δ͜ͱ
    • Open APIͱؔ࿈༻ޠͷઆ໌(͸͡Ίͯͷํ޲͚)
    • STORESͰͷRSpecΛ࢖ͬͨOpen API
    (APIυΩϡϝϯτ)ͷࣗಈςετ·ͰͷܦҢ
    • RSpec ❌ Open APIͷӡ༻ͱ൵تަʑ

    View Slide

  4. ࠓճ͓࿩͠ͳ͍͜ͱ
    • RSpecͦͷ΋ͷͷ஌ݟ΍ಥͬࠐΜͩ಺༰
    • RSpec ❌ Open API ͷ
    ϕετϓϥΫςΟεతͳ࿩
    (໛ࡧதͰͯ͠…

    View Slide

  5. ໨࣍
    ɾOpen APIͱؔ࿈༻ޠͷઆ໌
    ɾOpen APIࣗಈςετӡ༻
    ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

    View Slide

  6. ໨࣍
    ▶︎ Open APIͱؔ࿈༻ޠͷઆ໌
    ɾOpen APIࣗಈςετӡ༻
    ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

    View Slide

  7. Open APIͬͯͳʹʁ
    • REST APIͷAPIυΩϡϝϯτͷ
    هड़ϑΥʔϚοτͷ͜ͱ
    • ͦͷϑΥʔϚοτʹج͍ͮͯॻ͔Εͨ
    APIυΩϡϝϯτΛ
    ※Open API SpecificationͱݺͿ
    ※ ҰൠతʹOpen APIͱݴͬͨ৔߹͸
    Open API SpecificationΛҙຯ͢Δ͜ͱ͕ଟ͍

    View Slide

  8. Open APIؔ࿈༻ޠ
    Swagger

    View Slide

  9. SwaggerͬͯͳΜ͚ͩͬʁ
    • Open APIͷ࢓༷ʹج͍ͮͨAPIυΩϡϝϯτ
    ͷ࡞੒Λࢧԉ͢ΔΦʔϓϯιʔεπʔϧ܈
    • Open API Initiative(OAI)ͱ͍͏REST APIͷ
    ΠϯλʔϑΣʔεͷඪ४Խஂମʹ࠾༻͞Εͨ

    View Slide

  10. ओͳSwaggerπʔϧ
    • Swagger Edittor
    (ϒϥ΢β΍ϩʔΧϧͰOpen APIΛهड़ग़དྷΔΤσΟλʔ)
    • Swagger UI
    (Open APIͷهड़ΛಈతʹAPIυΩϡϝϯτͱͯ͠ϨϯμϦ
    ϯά͢Δπʔϧ)
    • Swagger Codegen
    (Open API͔Βαʔόʔ/ΫϥΠΞϯτͷίʔυΛੜ੒͢Δ
    πʔϧ)

    View Slide

  11. ͞ΒʹৄࡉΛ஌Γ͍ͨ৔߹͸ެࣜΛࢀর

    View Slide

  12. ໨࣍
    ɾOpen APIͱؔ࿈༻ޠͷઆ໌
    ɾOpen APIࣗಈςετӡ༻
    ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

    View Slide

  13. ໨࣍
    ɾOpen APIͱؔ࿈༻ޠͷઆ໌
    ▶︎ Open APIࣗಈςετӡ༻
    ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

    View Slide

  14. ςετͷ࿩ͷલʹSTORESͰ
    Open APIΛӡ༻͍ͯ͘͠Α͏ʹ
    ͳͬͨܦҢΛઆ໌

    View Slide

  15. STORESͷ
    ϑϩϯτ/όοΫΤϯυͷঢ়ଶ
    ϑϩϯτΤϯυ όοΫΤϯυ
    ˞Ұ෦"OHVMBS+4
    ݱࡏ

    ϦΫΤετ
    Ϩεϙϯε +40/

    View Slide

  16. Open APIಋೖҎલɿ
    ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ
    ϑϩϯτΤϯυ όοΫΤϯυ
    ˞Ұ෦"OHVMBS+4
    ݱࡏ

    "1*ͷεΩʔϚ͕
    ཉ͍͠Ͱ͢ʂ
    Ͳ͏͠Α͏ʜ

    View Slide

  17. Open APIಋೖҎલɿ
    ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ
    ϑϩϯτΤϯυ όοΫΤϯυ
    ˞Ұ෦"OHVMBS+4
    ݱࡏ

    ͋Γ͕ͱ͏
    ͍͟͝·͢ ࠔ࿭

    FTBʹॻ͖·ͨ͠

    View Slide

  18. Open APIҎલɿ
    ͱ͋ΔҊ݅ͰͷAPIυΩϡϝϯτ

    View Slide

  19. markdownͷAPIυΩϡϝϯτΛ
    ࢓༷มߋͷͨͼʹ๨Εͣʹ
    ߋ৽͢Δͷ͠ΜͲ͍…

    View Slide

  20. ͕࣌ܦͪ… ⏳
    Open APIΛ࢖ͬͨ։ൃ΁Ҡߦ

    View Slide

  21. Open APIಋೖҎ߱ɿ
    ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ
    ϑϩϯτΤϯυ όοΫΤϯυ
    ˞Ұ෦"OHVMBS+4
    ݱࡏ

    "1*
    εΩʔϚ
    Λڠۀͯ͠࡞੒

    View Slide

  22. Open APIಋೖҎ߱ɿ
    ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ
    ϑϩϯτΤϯυ .PDLαʔόʔ
    ˞Ұ෦"OHVMBS+4
    ݱࡏ

    IUUQBQJWCMPHT
    Ϩεϙϯε +40/
    ˞4XBHHFSπʔϧ
    4UPQMJHIU4UVEJP࢖༻

    View Slide

  23. Α͏΍͘ςετͷ࿩

    View Slide

  24. APIεΩʔϚΛϑϩϯτ/όοΫΤϯ
    υͰڞ༗ग़དྷΔΑ͏ʹͳͬͨ
    ͱ͸͍͑…
    εΩʔϚͷ༗ޮੑνΣοΫΛ
    खಈͰ΍Δͱഁ୼ͦ͠͏

    View Slide

  25. ࣗಈԽͩʂʂʂʂ

    View Slide

  26. Open APIࣗಈςετ
    ςετίʔυ 0QFO"1* "1*υΩϡϝϯτ

    View Slide

  27. Open APIࣗಈςετ
    ςετίʔυ 0QFO"1* "1*υΩϡϝϯτ

    ίίͷ࢓૊ΈΛৄ͘͠

    View Slide

  28. RSpec ❌ Open APIͷৄࡉ
    committee-rails ͱ͍͏
    gemΛ࢖ͬͯ
    RSpecͰAPIεΩʔϚ(YAML)ͱ
    APIͷࠩ෼ΛνΣοΫ

    View Slide

  29. committee-railsͷ࢖͍ํ


    describe 'Api::V1::BlogsController', type: :request do
    include Committee::Rails::Test::Methods
    def committee_options
    @committee_options ||= {
    schema_path: Rails.root.join('APIεΩʔϚͷύε'),
    old_assert_behavior: false
    }
    end
    describe 'GET /api/v1/blogs' do
    it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do
    get '/api/v1/blogs'
    assert_response_schema_confirm
    end
    end
    end

    View Slide

  30. committee-railsͷ࢖͍ํ


    describe 'Api::V1::BlogsController', type: :request do
    include Committee::Rails::Test::Methods
    def committee_options
    @committee_options ||= {
    schema_path: Rails.root.join('APIεΩʔϚͷύε'),
    old_assert_behavior: false
    }
    end
    describe 'GET /api/v1/blogs' do
    it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do
    get '/api/v1/blogs'
    assert_response_schema_confirm
    end
    end
    end
    APIεΩʔϚͷಡΈࠐΈ

    View Slide

  31. committee-railsͷ࢖͍ํ


    describe 'Api::V1::BlogsController', type: :request do
    include Committee::Rails::Test::Methods
    def committee_options
    @committee_options ||= {
    schema_path: Rails.root.join('APIεΩʔϚͷύε'),
    old_assert_behavior: false
    }
    end
    describe 'GET /api/v1/blogs' do
    it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do
    get '/api/v1/blogs'
    assert_response_schema_confirm
    end
    end
    end
    εΩʔϚݕূ༻ϝιουͷఆٛݩΫϥεͷಡΈࠐΈ

    View Slide

  32. committee-railsͷ࢖͍ํ


    describe 'Api::V1::BlogsController', type: :request do
    include Committee::Rails::Test::Methods
    def committee_options
    @committee_options ||= {
    schema_path: Rails.root.join('APIεΩʔϚͷύε'),
    old_assert_behavior: false
    }
    end
    describe 'GET /api/v1/blogs' do
    it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do
    get '/api/v1/blogs'
    assert_response_schema_confirm
    end
    end
    end
    APIεΩʔϚͱ࣮ࡍͷAPIͷ஋ͷݕূ

    View Slide

  33. ໨࣍
    ɾOpen APIͱؔ࿈༻ޠͷઆ໌
    ɾOpen APIࣗಈςετӡ༻
    ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

    View Slide

  34. ໨࣍
    ɾOpen APIͱؔ࿈༻ޠͷઆ໌
    ɾOpen APIࣗಈςετӡ༻
    ▶︎ Open APIࣗಈςετӡ༻͔Βͷֶͼ

    View Slide

  35. ศརʹͳͬͨ൓໘
    ৭ʑͱࢼߦࡨޡͨ͠

    ͜ͱ͕͋ͬͨͷͰ

    ͦͷ͓࿩Λ…

    View Slide

  36. ࣄҊ1:
    ͋Ε…ςετམͪͳ͘ͳ͍ʁ

    View Slide

  37. APIΛมߋͯ͠ɺ
    ࣮૷ͱεΩʔϚͷؒʹ
    ࠩ෼͕͋Δͷʹ
    CI͕௨ͬͯΔ…

    View Slide

  38. committee-railsͷམͱ݀͠⛳

    View Slide

  39. assert_request_schema
    (assert_response_schema)Ͱݕূ͞ΕΔύϥϝʔλ͸
    required Ͱࢦఆͨ͠ϑΟʔϧυ͚ͩ
    post:
    summary: POST /api/v1/blogs
    description: ϒϩά࡞੒API
    tags:
    - blog
    requestBody:
    content:
    application/json:
    type: object
    properties:
    blog:
    type: object
    required:
    - title
    - content
    ݟͯΔͷίί͚ͩ

    View Slide

  40. ղܾࡦ

    View Slide

  41. ޙड़͢ΔͷͰҰ୴εΩοϓ

    View Slide

  42. ࣄҊ2:
    ҟৗܥͷAPIεΩʔϚͱ
    ͦͷςετͲ͏͢Δʁ

    View Slide

  43. ྫ͑͹͜Μͳ৔߹ͷ࿩
    class BlogsController < ApplicationController
    ※தུ

    def create

    ※தུ
    begin
    ※ਖ਼ৗܥͷॲཧ
    rescue ::Mongoid::Errors::Validations
    render status: :bad_request, json: {
    errors: blog.errors
    }
    end
    end

    View Slide

  44. ྫ͑͹͜Μͳ৔߹ͷ࿩
    class BlogsController < ApplicationController
    ※தུ

    def create

    ※தུ
    begin
    ※ਖ਼ৗܥͷॲཧ
    rescue ::Mongoid::Errors::Validations
    render status: :bad_request, json: {
    errors: blog.errors
    }
    end
    end ͦ΋ͦ΋ίίͷ෦෼ͷৄࡉΛͲ͜·Ͱ
    APIυΩϡϝϯτʹ࢒͔͢໰୊

    View Slide

  45. ղܾࡦ

    View Slide

  46. YAMLʹ͸࠷௿ݶͷεςʔλείʔυͱ
    Τϥʔ಺༰ͷ഑ྻ͕ฦͬͯ͘Δ͜ͱ͚ͩΛఆٛ
    responses:
    ※தུ
    '400':
    description: Bad Request
    content:
    application/json:
    schema:
    type: object
    properties:
    errors:
    type: array
    blogs: {}
    required:
    - errors
    Τϥʔ഑ྻ͕ඞਢͰ͋Δ
    ͜ͱ͚ͩఆٛ͢Ε͹Α͠
    ͱͨ͠

    View Slide

  47. ͜ͷ෦෼ʹ͍ͭͯ͸౰֘API͕
    ಛఆগ਺ͷ։ൃऀ޲͚(SSKDs)APIͳͷͰ
    ෆಛఆଟ਺ͷ։ൃऀ޲͚(LSUDs)API΄Ͳ
    γϏΞͰ͸ͳ͍఺͕͋Δ͔΋…

    View Slide

  48. ࣄҊ3:
    CSVΞοϓϩʔυ
    (μ΢ϯϩʔυ) APIͷ
    εΩʔϚͱͦͷςετ
    Ͳ͏͢Δʁ

    View Slide

  49. ͦ΋ͦ΋CSVϑΝΠϧͷத਎
    ·ͰOpen APIͰఆٛ͢Δ΋ͷ
    ͳͷ͔ʁ

    View Slide

  50. ͜Μͳstack overflowΛൃݟ

    View Slide

  51. APIͷϨεϙϯεͷCSVΛ
    Open APIͷYAMLͰ
    Ͳ͏ॻ͘ͷʁతͳ࣭໰

    View Slide

  52. ͦͷճ౴͕ͪ͜Β

    View Slide

  53. ʻ༁ʼ
    Open API ࢓༷Ͱ͸ CSV ϨεϙϯεͷྫΛఏڙ
    ͍ͯ͠·ͤΜɻ
    ͦͷͨΊɺεΩʔϚ͸จࣈྻܕɺ
    จࣈྻͷ഑ྻɺ·ͨ͸ۭͷεΩʔϚͷ͍ͣΕ͔
    ʹͳΓ·͢ɻ(͜Ε͸ʮ೚ҙͷ஋ʯΛҙຯ͠·͢)

    View Slide

  54. ʻ༁ʼ
    Open API ࢓༷Ͱ͸ CSV ϨεϙϯεͷྫΛఏڙ
    ͍ͯ͠·ͤΜɻ
    ͦͷͨΊɺεΩʔϚ͸จࣈྻܕɺ
    จࣈྻͷ഑ྻɺ·ͨ͸ۭͷεΩʔϚͷ͍ͣΕ͔
    ʹͳΓ·͢ɻ(͜Ε͸ʮ೚ҙͷ஋ʯΛҙຯ͠·͢)

    View Slide

  55. ͔֬ʹ…ެࣜΛௐ΂ͯ΋ͦΕΒ͍͠
    ྫ͸ͳ͔ͬͨ
    (2020.08࣌఺)

    View Slide

  56. ϑϩϯτ/όοΫΤϯυͰڞ༗͍ͨ͜͠ͱɺ
    ࣮૷ͱOpen APIͷఆٛͷҰகΛ
    Ͳ͜·Ͱݕূ͢΂͖͔ٞ࿦

    View Slide

  57. ղܾࡦ

    View Slide

  58. Content-Type ͕ text/csv ʹͳ͍ͬͯΔ͜ͱɺ
    εςʔλείʔυͷ֬ೝ ͕࠷௿ݶग़དྷΕ͹
    OKͱ͢Δ͜ͱʹ
    requestBody:
    content:
    text/csv:
    schema:
    type: string
    responses:
    '200':
    description: OK
    content:
    text/csv:
    schema:
    type: string

    View Slide

  59. ݁ہͷͱ͜Ζ
    Ͳ͜·Ͱςετ͢Δʁ
    ໰୊

    View Slide

  60. required Ͱࢦఆ͠ͳ͔ͬͨ
    ϑΟʔϧυ͸ݕূग़དྷͳ͍͚Ͳ
    ͍͍ͷ͔ʁ

    View Slide

  61. required Ͱࢦఆ͑͢͠͞Ε͹
    ҰԠνΣοΫ͸ग़དྷΔ͚Ͳ
    ͦΕͰ͍͍ͷ͔ʁ… (೰·͍͠

    View Slide

  62. ϑϩϯτΤϯυͱ
    όοΫΤϯυͰ
    ࿩͠߹ͬͨ݁Ռ

    View Slide

  63. ݁࿦

    View Slide

  64. RSpec࣮ߦ࣌ʹ
    required Ͱࢦఆ͠ͳ͍ͱ
    εΩʔϚνΣοΫग़དྷͳ͍ͷ͸
    αʔόʔαΠυͷϥΠϒϥϦ
    (committee-rails)ͷ౎߹ʂ
    APIεΩʔϚʹ͸αʔόʔαΠυଆ
    ͷ౎߹ΛͳΔ΂͘൓ө͠ͳ͍

    View Slide

  65. ɾԿΛ
    ɾͲ͜·Ͱ
    ɾͲΜͳ෩ʹ
    APIεΩʔϚͱͯ͠
    ఆٛ͠ɺςετ͍͔ͯ͘͠͸
    ໌֬ͳਖ਼ղ͕ͳ͍ͷͰ೰Ή

    View Slide

  66. ղܾࡦ

    View Slide

  67. ਖ਼ղ͕ແ͍͔Βɺ
    ࣗ෼ͨͪͰ
    ϧʔϧΛ࡞Δ

    View Slide

  68. ελΠϧΨΠυΛ
    ࡞੒ͯࣾ͠಺esaͰγΣΞ
    ࣗ෼ͨͪͷ൑அ࣠Λ࣋ͭΑ͏
    ʹ͍ͯ͠Δ

    View Slide

  69. ɾOpen APIͷςετʹcommittee-rails͸
    ɹ༗༻✨
    ɾͱ͸͍͑…Open API͸શͯΛࣗಈԽͨ͠
    ɹςετͰΧόʔ͖͠Εͳ͍ͷͰ஫ҙ
    ɾOpen APIͷςετपΓ͸໌֬ͳਖ਼ղ͕
    ɹͳ͍ͷͰɺͲ͜·ͰΛݕূ͢Δ͔͸
    ɹͦͷΞϓϦͷཁ݅࣍ୈ
    ·ͱΊ

    View Slide

  70. ࠂ஌

    View Slide

  71. ͪ͜Β΋ੋඇνΣοΫͯ͠Έ͍ͯͩ͘͞
    ςοΫϒϩά࢝Ί·ͨ͠

    View Slide

  72. ͝ਗ਼ௌ͋Γ͕ͱ͏
    ͍͟͝·ͨ͠

    View Slide