Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RSpecでBDDをしよう

56bb00f9220a46a94cf9b5208786a05a?s=47 y@su
July 14, 2018

 RSpecでBDDをしよう

Rails Developers Meetup 2018 Day 3 Extreme

TDD→BDD→俺がやってるRSpecの書き方を狙ったけどRSpecの部分をやっていると時間が足り無さ過ぎて無理でしたw

56bb00f9220a46a94cf9b5208786a05a?s=128

y@su

July 14, 2018
Tweet

More Decks by y@su

Other Decks in Technology

Transcript

  1. RSpecͰBDDΛ͠Α͏ Rails Developers Meetup 2018 Day3 Yasuhiko Katoh @yatmsu

  2. ࣗݾ঺հ ▪Twitter: @yatmsu ▪GitHub: @yatmsu ▪ॴଐ: גࣜձࣾυϦίϜ(6/1ʙ) ▪Railsྺ: 10೥͙Β͍ •

    Ver 1.2.x ʙ
  3. ࠓ೔࿩͢͜ͱ TDD / BDD / RSpec ฉ͍ͯཉ͍͠ਓ෺૾ • एखͷRailsΤϯδχΞ(ब৬͢Δ·Ͱίʔυॻ͍ͯͳ͔ͬͨͱ͔) •

    RSpec͸୯७ʹςετίʔυΛॻ͘ҝʹ࢖͍ͬͯΔΑͱ͍͏ΤϯδχΞ • ͦΕҎ֎ͷਓͰ΋OKͰ͢ ※ ৭ʑ͋ͬͯRSpecʹ͸͋·Γݴٴ͍ͯ͠ͳ͍Ͱ͢ɾɾ
  4. TDD

  5. Test Driven Development ςετۦಈ։ൃ

  6. TDDͷྺ࢙(؆қ൛) w ೥%%.D$SBDLFO͕%JHJUBM$PNQVUFS1SPHSBNNJOHzΛग़൛ w ιϑτ΢ΣΞςετٕज़ʹ͍ͭͯॻ͔Εͨ࠷ॳͷॻ੶ w ೥୅͸σόοάɾςετɾɾɾ౳ͷ֓೦͕۠ผ͞Ε͍ͯͳ͔ͬͨ࣌୅ w ʮςετʯͱ͍͏༻ޠ͕࢖ΘΕ͍ͯͳ͍ ֘౰͢ΔՕॴͷষ໊͸l1SPHSBN$IFDLPVUz

     ʙ5%%͋·Γ࠾༻͞Εͳ͔ͬͨظؒʙ w ೥,FOU#FDL͕46OJUΛ։ൃ w ޙͷY6OJUͷݩʹͳΔϢχοτςετϑϨʔϜϫʔΫ w 5%%ͷݪܕͱͳΔϓϩάϥϛϯάख๏΍ςετΛར༻ͨ͠ϦϑΝΫλϦϯάͷߟ͑ํ͕ ஝ੵ͞Ε͍ͯ͘ɻ w %JHJUBM$PNQVUFS1SPHSBNNJOHzͷଘࡏ͕͋ΔͷͰɺ5%%Λൃ໌ͨ͠ͷͰ͸ͳ͘ɺ ʮ5%%Λ࠶ൃݟʯͨ͠ͱݴΘΕ͍ͯΔɻ
  7. TDDͷྺ࢙(؆қ൛) w ೥,FOU#FDL͕ʮ91ΤΫετϦʔϜɾϓϩάϥϛϯάೖ໳ʯ &YUSFNF 1SPHSBNNJOH&YQMBJOFE&NCSBDF$IBOHF Λग़൛ w ೥,FOU#FDL͕ʮςετۦಈ։ൃೖ໳ʯ 5FTU%SJWFO%FWFMPQNFOUCZ&YBNQMF Λग़൛

    w 46OJU࡞੒࣌ʹ࠶ൃݟͨ͠5%%Λߏ੒͢ΔཁૉΛମܥతʹ੔ཧͨ͠಺༰ w ʮ5%%ͷݪయʯͱݺ͹ΕΔॻ੶ ɾɾɾɾɾ
  8. TDDͷਐΊํ 1. ࠷ॳʹςετίʔυΛ1ͭॻ͘(ςετϑΝʔετ) 2. 1.Λ࣮ߦ͠ɺࣦഊ͢Δ͜ͱΛ֬ೝ͢Δ (Red) 3. 2.ͷςετ͕੒ޭ͢ΔΑ͏ʹ࠷খݶͷϓϩμΫτίʔυΛॻ͘ 4. 3.Λ࣮ߦ͠ɺ੒ޭ͢Δ͜ͱΛ֬ೝ͢Δ

    (Green) 5. ϓϩμΫτίʔυͷৼΔ෣͍Λม͑ͳ͍Α͏ʹϦϑΝΫλϦϯάΛߦ͏ (Refactor) 6. 1.ʹ໭Δ ͬ͘͟Γݴ͏ͱ͜ͷ։ൃαΠΫϧΛ܁Γฦ͍ͯ͘͠ͷ͕TDDͰ͢ɻ
  9. 3FGBDUPS (3&&/ 3&% TDDͷϚϯτϥ ͜ͷαΠΫϧΛߴ଎Ͱ܁Γฦ͍ͯ͘͠

  10. ࣮ࡍʹ΍ͬͯΈΔ

  11. ࣮૷͍ͨ͠ػೳ • Ϣʔβʔ͕ΞΧ΢ϯτΛ࡞੒͢Δػೳ લఏ৚݅ • ؅ཧը໘ܥͷRailsΞϓϦΛ։ൃதͰ͋Δ • migrationϑΝΠϧ͸লུ(name, emailͱ ͍͏ΧϥϜ͕͋Δusersςʔϒϧ͕͋Δ΋

    ͷͱ͠·͢)
  12. UserϞσϧͷSpecΛ࡞੒ require 'rails_helper' RSpec.describe User, type: :model do end ͜͜·Ͱॻ͍ͨΒςετΛଈ࣮ߦ͠·͢

  13. ࣮ߦ(RED) $ bin/rspec spec/models/user_spec.rb An error occurred while loading ./spec/models/user_spec.rb.

    Failure/Error: RSpec.describe User, type: :model do NameError: uninitialized constant User No examples found. Finished in 4.46 seconds (files took 8.57 seconds to load) 0 examples, 0 failures, 1 error occurred outside of examples ࣦഊ͢Δ͜ͱΛ֬ೝ
  14. UserϞσϧΛ࡞੒ class User < ApplicationRecord end ςετΛଈ࣮ߦ͠·͢

  15. ࣮ߦ(Green) $ bin/rspec spec/models/user_spec.rb 
 No examples found. Finished in

    2.69 seconds (files took 7.16 seconds to load) 0 examples, 0 failures ੒ޭ͢Δ͜ͱΛ֬ೝ
  16. ϦϑΝΫλϦϯά(Refactor) class User < ApplicationRecord end ϞσϧΛ࡞͚ͬͨͩͳͷͰࠓճ͸ແ͠

  17. #register_userͷςετΛ1ͭ௥Ճ require 'rails_helper' RSpec.describe User, type: :model do describe '#register_user'

    do let(:user) { create :user } it 'trueΛฦ͢͜ͱ' do expect(user.register_user('Ϣʔβʔ໊', 'hoge@hoge.com')).to eq true end end end ॻ͘ςετ͸ͭͷΈ
  18. ࣮ߦ(RED) $ bin/rspec spec/models/user_spec.rb User #register_user trueΛฦ͢͜ͱ (FAILED - 1)

    Failures: 1) User#register_user trueΛฦ͢͜ͱ Failure/Error: expect(user.register_user('Ϣʔβʔ໊', 'hoge@hoge.com')).to eq true NoMethodError: undefined method `register_user' for #<User:0x007fc64f14db98> Finished in 4.49 seconds (files took 10.77 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/models/user_spec.rb:7 # User#register_user trueΛฦ͢͜ͱ ࣦഊ͢Δ͜ͱΛ֬ೝ
  19. #register_userϝιουΛ௥Ճ class User < ApplicationRecord def register_user(name, email) true end

    end ςετΛ௨͢࠷খݶͷίʔυΛ࣮૷͢Δ͜ͱ ࠷খݶͷίʔυͳͷͰ͜ΕͰྑ͍
  20. ࣮ߦ(Green) $ bin/rspec spec/models/user_spec.rb User #register_user trueΛฦ͢͜ͱ Finished in 3.16

    seconds (files took 6.98 seconds to load) 1 example, 0 failures ੒ޭ͢Δ͜ͱΛ֬ೝ
  21. ϦϑΝΫλϦϯά(Refactor) class User < ApplicationRecord def register_user(name, email) true end

    end ඞཁͳͦ͞͏ɻࠓճ͸ແ͠ɻ
  22. #register_userͷςετΛ1ͭ௥Ճ require 'rails_helper' RSpec.describe User, type: :model do describe '#register_user'

    do let(:user) { create :user } it 'trueΛฦ͢͜ͱ' do expect(user.register_user('Ϣʔβʔ໊', 'hoge@hoge.com')).to eq true end it 'usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ' do expect { user.register_user('Ϣʔβʔ໊', 'hoge@hoge.com') }.to change { described_class.where(name: 'Ϣʔβʔ໊', email: 'hoge@hoge.com').exists? }.from(false).to(true) end end end ॻ͘ςετ͸΍͸ΓͭͷΈ
  23. ࣮ߦ(RED) $ bin/rspec spec/models/user_spec.rb User #register_user trueΛฦ͢͜ͱ usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ (FAILED -

    1) Failures: 1) User#register_user usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ Failure/Error: expect { user.register_user('Ϣʔβʔ໊', 'hoge@hoge.com') }.to change { described_class.where(name: 'Ϣʔβʔ໊', email: 'hoge@hoge.com').exists? }.from(false).to(true) expected `described_class.where(name: 'Ϣʔβʔ໊', email: 'hoge@hoge.com').exists?` to have changed from false to true, but did not change Finished in 2.95 seconds (files took 9.34 seconds to load) 2 examples, 1 failure Failed examples: rspec ./spec/models/user_spec.rb:11 # User#register_user usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ ࣦഊ͢Δ͜ͱΛ֬ೝ
  24. #register_userϝιουΛߋ৽ class User < ApplicationRecord def register_user(name, email) user =

    User.new user.name = name user.email = email user.save end end ςετΛ௨͢࠷খݶͷίʔυΛ࣮૷͢Δ͜ͱ ͱʹ͔͘ಈ͘ίʔυΛॻ͚͹͍͍
  25. ࣮ߦ(Green) $ bin/rspec spec/models/user_spec.rb User #register_user trueΛฦ͢͜ͱ usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ Finished in

    3.5 seconds (files took 8.05 seconds to load) 2 examples, 0 failures ੒ޭ͢Δ͜ͱΛ֬ೝ
  26. ϦϑΝΫλϦϯά(Refactor) class User < ApplicationRecord def register_user(name, email) user =

    User.new(name: name, email: email) user.save end end ;ͭ͏ʹOFXͰύϥϝʔλ౉ͤ͹͍͍ΑͶ
  27. ࣮ߦ(Green) $ bin/rspec spec/models/user_spec.rb User #register_user trueΛฦ͢͜ͱ usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ Finished in

    3.5 seconds (files took 8.31 seconds to load) 2 examples, 0 failures ੒ޭ͢Δ͜ͱΛ֬ೝ 4QFD͕͋Ε͹ϦϑΝΫλϦϯά͠΍͍͢
  28. TDD͸ιϑτ΢ΣΞςετٕ๏ͷ 1ͭͩͱޡղ͍ͯ͠Δਓ͕ଟ͍͚Ͳɺ ͜͜·Ͱ΍ͬͯΈΔͱTDDͷຊ࣭͸ ʮςετʯͰ͸ແ͍ͱ͍͏ࣄʹؾ෇͘͸ͣɻ ※࣮ࡍʹࣗ෼ͰखΛಈ͔ͯ͠ΈΔͱΑΓཧղग़དྷ·͢ɻ

  29. Kent Beck “Test-Driven Development: By Example” “ൽ೑ͳ͜ͱʹɺTDD͸ςετٕ๏Ͱ͸ͳ͍ (CunninghamͷެҊ)ɻ TDD͸෼ੳٕ๏Ͱ͋Γɺઃܭٕ๏Ͱ͋Γɺ ࣮ࡍʹ͸։ൃͷ͢΂ͯͷΞΫςΟϏςΟΛ

    ߏ଄Խ͢Δٕ๏ͳͷͩɻ”
  30. Kent Beck “Test-Driven Development: By Example” “ൽ೑ͳ͜ͱʹɺTDD͸ςετٕ๏Ͱ͸ͳ͍ (CunninghamͷެҊ)ɻ TDD͸෼ੳٕ๏Ͱ͋Γɺઃܭٕ๏Ͱ͋Γɺ ࣮ࡍʹ͸։ൃͷ͢΂ͯͷΞΫςΟϏςΟΛ

    ߏ଄Խ͢Δٕ๏ͳͷͩɻ”
  31. TDD·ͱΊ • TDDͱ͸ϓϩάϥϜʹඞཁͳ֤ػೳʹ͍ͭͯɺ·ͣ ςετίʔυΛॻ͖(ςετϑΝʔετ)ɺͦͷςετ ͕ಈ࡞͢Δඞཁ࠷௿ݶͳ࣮૷Λߦ͍ɺϦϑΝΫλϦ ϯάΛߦ͏ɾɾͱ͍͏޻ఔΛ୹͍αΠΫϧͰߴ଎ʹ ܁Γฦ͢։ൃελΠϧ • TDDͱ͸ςετٕ๏Ͱ͸ͳ͘ɺઃܭٕ๏Ͱ͋Δɻ

  32. ͱɺ͍͏Α͏ͳษڧձΛաڈʹ ࣾ಺ษڧձͰ࿩ͨ͜͠ͱ͕͋Γɺ ͦͷ௚ޙʹ࢝·ͬͨࡶஊͰɾɾɾ

  33. .JOJUFTUͬͯͲ ͏ͳΜͰ͔͢ʁ

  34. .JOJUFTUͬͯͲ ͏ͳΜͰ͔͢ʁ ςετͷΧόϨο δͬͯԿΛ௒͍͑ͯ Δ΂͖ʁ

  35. .JOJUFTUͬͯͲ ͏ͳΜͰ͔͢ʁ ϫγͷए͍ࠒ ͸&YDFMʹςετ έʔεΛॻ͍͍ͯͬ ͯɾɾɾ ຊ൪؀ڥͷσʔ λͰͳ͍ͱ࠶ݱ͠ͳ ͍όά͸Ͳ͏΍ͬͯς ετͨ͠Βɾɾɾ

    ςετͷΧόϨο δͬͯԿΛ௒͍͑ͯ Δ΂͖ʁ ʮςετʯͷ࿩୊͹͔Γʂʂ
  36. Կނ͜͏ͳͬͯ͠·͏ͷ͔ʁ TDD͸ςετٕ๏Ͱ͸ͳ͍ɻ ͱ͍͏࿩Λͨ͠௚ޙͳͷʹɻ ୭΋Զͷ࿩Λฉ͍ͯͳ͔ͬͨՄೳੑ͕ɾɾɾ

  37. ࿩Λฉ͍͍ͯͳ͔ͬͨΘ͚Ͱ͸ͳ͍(ͱ৴͍ͨ͡) ͦΕ͚ͩʮςετʯͱ͍͏ݴ༿ͷΠϝʔδ͕ڧ͍ͱ͍͏͜ͱ ʮςετʯͱ͍͏ݴ༿Λ஌͍ͬͯΔਓ͸ଟ͍ɻ ʮςετʯͱ͍͏ݴ༿Λฉ͍ͨ࣌఺ͰɺͦΕͧΕ ͕ࢥ͍ඳ͘ʮςετʯʹ͍ͭͯ࿈૝ͯ͠͠·ͬͨ ͷͰ͸ͳ͍͔ɻ ʮTDD = ιϑτ΢ΣΞςετٕ๏ʯ ͱ͍͏ೝࣝʹͳͬͯ͠·ͬͨʁ

  38. “TDD͸ɺςετͱ͍͏ݴ༿͕࣋ͭχϡΞϯεͷ໰୊ʹ௚໘͍ͯ͠·ͨ͠ɻςε τͱ͍͏୯ޠͱɺͦΕʹ·ͭΘΔޠኮΛ࢖͍ͬͯΔݶΓɺTDD͸ʮٕज़ऀ͕ɺ Ͳ͏࡞Δ͔ʯʹ࢖͏΋ͷͰ͋Δͱ͍͏ઌೖ؍ʹٯΒ͑ͣɺTDDͷਖ਼֬ͳཧղͱ ܒ໤ʹ͸ࢸΒͳ͍ͷͰ͸ͳ͍͔ͱ͍͏໰୊ҙࣝͰ͢ɻ” ൈਮ:: Kent Beck “Test-Driven Development: By

    Example” ෇࿥C TDDࢧ࣋೿ͷίϛϡχςΟͰ͜ͷ݅͸ٞ࿦ʹͳͬͨɻ ʮTDDʯͰ͸ବ໨ͰޠኮΛม͑ͳ͚Ε͹ͳΒͳ͍ɻ TDDͷTͷ෦෼ʹTestΛ࢖͍ͬͯΔݶΓɺTDD͕ਖ਼͘͠ཧղ ͞ΕΔ͜ͱ͸೉͍͠ɻ ͜͜ͰDanNorth͕ൃݟͨ͠ޠኮ͕ɺɺɺ TDDͱ͍͏ݴ༿๊͕͑Δ໰୊
  39. Behavior ৼΔ෣͍

  40. BDD

  41. Behavior Driven Development ৼ෣ۦಈ։ൃ

  42. ޠኮͷมߋͱRSpecͷ஀ੜ BTTFSUJPOˠFYQFDUBUJPO UFTUˠFYBNQMF UFTUDBTFˠFYBNQMFHSPVQ UFTUDMBTTˠTQFD w +#FIBWF +BWB ͕։ൃ͞Εͨ %BO/PSUI

    5%%ˠ#%%͚ͩͰͳ͘ɺ ؒҧͬͨઌೖ؍Λ༩͑ͳ͍Α͏ ʹɺޠኮΛมߋ 5%%ͷࠒͱ͸ޠኮΛஔ͖׵͑ͨςετϑϨʔϜϫʔΫΛ࡞੒ w 34QFD 3VCZ ͷ஀ੜ΁ %BWF"TUFMTɺ"TMBL)FMMFT”Z
  43. ޠኮ͕มΘΔͱࢥߟͷग़ൃ఺͕มΘΔ ςετ ςετΛॻ͜͏ ςετίʔυ Λॻ͘ ৼΔ෣͍ ৼΔ෣͍Λॻ͜͏ 4QFDΛॻ͘ #%%ͷαΠΫϧ΁ 5%%ͷ৔߹

    #%%ͷ৔߹ ˞ॻ͍͍ͯΔϑΝΠϧ͸શ͘ಉ͡
  44. BDDͷݱঢ় Behaviorͱ͍͏ޠኮͷൃݟʹΑΓɺ BDDͱ͍͏ޡղΛট͘ࣄͷͳ໊͍લ͕͍ͭͨ TDD͸ɺઌೖ؍Ͱޡղ͞ΕΔ͜ͱͳ͘ݱࡏ·Ͱ ਖ਼͘͠ೝࣝ͞Εͯීٴ͍ͯ͠·͢ɻ ΊͰͨ͠ΊͰͨ͠ɻ

  45. BDDͷݱঢ় ͱɺͳΔ͜ͱ͸ແ͔ͬͨ

  46. Aslak Hellesoy “Cucumber։ൃऀ” “TDD͸ςετͩͱ͍͏ޡղΛղͨ͘Ίʹ Dan NorthʹΑΓൃ໌͞ΕͨBDD͕ɺ14೥ ܦ͍ͬͨ·ɺਓʑʹςετͩͱޡղ͞Εͯ ͍Δͷ͸ൽ೑ͳ͜ͱͩɻ”

  47. Կނ͜͏ͳͬͯ͠·ͬͨͷ͔ʁ • BDDͷܒ໤ظ(2003೥ʙ2011೥ࠒ?) • ܒ໤׆ಈ͕ඞཁͩͬͨͷͰ׆ൃͳٞ࿦͕ߦΘΕɺଟ͘ͷ৘ใ͕ྲྀ ௨͍ͯͨ͠ɻ • BDDͷݱࡏ(2018೥) • ࢖༻͍ͯ͠Δݴޠ͸ؔ܎ͳ͘ɺςετίʔυΛॻ͘؀ڥ͕طʹͦ

    ͜ʹ͋Δͷ͕౰ͨΓલɻ • ʮͳͥςετίʔυΛॻ͘ͷ͔ʁʯͳΜͯߟ͑ͳ͍ɻ ྺ࢙ɾܦҢ౳͸ফ໓ RSpecଞπʔϧ܊͕࢒ͬͨ
  48. ΋ͬͱਂ͘஌Γͨ͘ͳͬͨΒ ෇࿥CΛಡ΋͏

  49. ͦΕͰ΋BDDΛ΍Δ͜ͱʹ͸ҙຯ͕͋Δ ▪ϝϦοτ •͍ͭͰ΋ϦϑΝΫλϦϯάΛߦ͑Δͱ͍͏ʮ҆৺ʯΛಘΒΕΔɻ •ৗʹৼΔ෣͍͕ఆٛ͞Ε͍ͯΔঢ়ଶͳͷͰɺมߋʹର͢Δڪා ͕ແ͘ͳΔɻ •ΠϯλʔϑΣʔεΛҙࣝͨ͠ઃܭ͕ग़དྷΔΑ͏ʹͳΔɻ •ςετϑΝʔετͷ͓͔͛Ͱɺ࠷ॳʹ࢖͍΍͍͢ΠϯλʔϑΣʔ εΛҙࣝͯ͠ઃܭ͢ΔΑ͏ʹͳΔɻ(ػೳ͹͔Γʹҙ͕ࣝ޲͔ Θͳ͍) •ςελϏϦςΟͷߴ͍ϞδϡʔϧΛ࣮૷͢ΔΑ͏ʹͳΔɻ(ૄ݁߹

    ͳ࣮૷) •etc….(ଞଟ਺!!
  50. ͦΕͰ΋BDDΛ΍Δ͜ͱʹ͸ҙຯ͕͋Δ ▪σϝϦοτ •ςελϏϦςΟ͕ߴ͍ઃܭ≠ྑ͍ઃܭ ͱ͸ݶΒͳ͍ •ա৒ʹؒ઀૚Λಋೖͯ͠͠·͏Մೳੑ •ʮϢχοτςετΛ͠΍͘͢͢Δࣄʯࣗମ͕໨త Ͱؒ઀૚Λಋೖͯ͠͠·͏͜ͱ΋ •ؒ઀૚͕૿͑Δͱ͍͏͜ͱ͸ɺ؅ཧ͠ͳ͚Ε͹ͳ Βͳ͍ΦϒδΣΫτ͕૿͑ͯ͠·͏ͱ͍͏͜ͱ

  51. BDDΛ࢝ΊΑ͏ʂ ΋͠ɺBDDΛ΍ͬͨ͜ͱ͕ͳ͍ͱ͍͏ਓ͕͍ͨ Βੋඇ࢝Ί͍ͯͩ͘͞ʂ νʔϜͰͷ։ൃʹ͔͠࢖͑ͳ͍ͱ͍͏΋ͷͰ͸ ͳ͘ݸਓͷٕज़ͳͷͰɺࠓ೔͔ΒͰ΋࢝ΊΔ͜ ͱ͕Ͱ͖·͢ɻ

  52. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ