Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

ࠓ೔࿩͢͜ͱ TDD / BDD / RSpec ฉ͍ͯཉ͍͠ਓ෺૾ • एखͷRailsΤϯδχΞ(ब৬͢Δ·Ͱίʔυॻ͍ͯͳ͔ͬͨͱ͔) • RSpec͸୯७ʹςετίʔυΛॻ͘ҝʹ࢖͍ͬͯΔΑͱ͍͏ΤϯδχΞ • ͦΕҎ֎ͷਓͰ΋OKͰ͢ ※ ৭ʑ͋ͬͯRSpecʹ͸͋·Γݴٴ͍ͯ͠ͳ͍Ͱ͢ɾɾ

Slide 4

Slide 4 text

TDD

Slide 5

Slide 5 text

Test Driven Development ςετۦಈ։ൃ

Slide 6

Slide 6 text

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%%Λ࠶ൃݟʯͨ͠ͱݴΘΕ͍ͯΔɻ

Slide 7

Slide 7 text

TDDͷྺ࢙(؆қ൛) w ೥,FOU#FDL͕ʮ91ΤΫετϦʔϜɾϓϩάϥϛϯάೖ໳ʯ &YUSFNF 1SPHSBNNJOH&YQMBJOFE&NCSBDF$IBOHF Λग़൛ w ೥,FOU#FDL͕ʮςετۦಈ։ൃೖ໳ʯ 5FTU%SJWFO%FWFMPQNFOUCZ&YBNQMF Λग़൛ w 46OJU࡞੒࣌ʹ࠶ൃݟͨ͠5%%Λߏ੒͢ΔཁૉΛମܥతʹ੔ཧͨ͠಺༰ w ʮ5%%ͷݪయʯͱݺ͹ΕΔॻ੶ ɾɾɾɾɾ

Slide 8

Slide 8 text

TDDͷਐΊํ 1. ࠷ॳʹςετίʔυΛ1ͭॻ͘(ςετϑΝʔετ) 2. 1.Λ࣮ߦ͠ɺࣦഊ͢Δ͜ͱΛ֬ೝ͢Δ (Red) 3. 2.ͷςετ͕੒ޭ͢ΔΑ͏ʹ࠷খݶͷϓϩμΫτίʔυΛॻ͘ 4. 3.Λ࣮ߦ͠ɺ੒ޭ͢Δ͜ͱΛ֬ೝ͢Δ (Green) 5. ϓϩμΫτίʔυͷৼΔ෣͍Λม͑ͳ͍Α͏ʹϦϑΝΫλϦϯάΛߦ͏ (Refactor) 6. 1.ʹ໭Δ ͬ͘͟Γݴ͏ͱ͜ͷ։ൃαΠΫϧΛ܁Γฦ͍ͯ͘͠ͷ͕TDDͰ͢ɻ

Slide 9

Slide 9 text

3FGBDUPS (3&&/ 3&% TDDͷϚϯτϥ ͜ͷαΠΫϧΛߴ଎Ͱ܁Γฦ͍ͯ͘͠

Slide 10

Slide 10 text

࣮ࡍʹ΍ͬͯΈΔ

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

࣮ߦ(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 ࣦഊ͢Δ͜ͱΛ֬ೝ

Slide 14

Slide 14 text

UserϞσϧΛ࡞੒ class User < ApplicationRecord end ςετΛଈ࣮ߦ͠·͢

Slide 15

Slide 15 text

࣮ߦ(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 ੒ޭ͢Δ͜ͱΛ֬ೝ

Slide 16

Slide 16 text

ϦϑΝΫλϦϯά(Refactor) class User < ApplicationRecord end ϞσϧΛ࡞͚ͬͨͩͳͷͰࠓճ͸ແ͠

Slide 17

Slide 17 text

#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('Ϣʔβʔ໊', '[email protected]')).to eq true end end end ॻ͘ςετ͸ͭͷΈ

Slide 18

Slide 18 text

࣮ߦ(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('Ϣʔβʔ໊', '[email protected]')).to eq true NoMethodError: undefined method `register_user' for # 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Λฦ͢͜ͱ ࣦഊ͢Δ͜ͱΛ֬ೝ

Slide 19

Slide 19 text

#register_userϝιουΛ௥Ճ class User < ApplicationRecord def register_user(name, email) true end end ςετΛ௨͢࠷খݶͷίʔυΛ࣮૷͢Δ͜ͱ ࠷খݶͷίʔυͳͷͰ͜ΕͰྑ͍

Slide 20

Slide 20 text

࣮ߦ(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 ੒ޭ͢Δ͜ͱΛ֬ೝ

Slide 21

Slide 21 text

ϦϑΝΫλϦϯά(Refactor) class User < ApplicationRecord def register_user(name, email) true end end ඞཁͳͦ͞͏ɻࠓճ͸ແ͠ɻ

Slide 22

Slide 22 text

#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('Ϣʔβʔ໊', '[email protected]')).to eq true end it 'usersςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ' do expect { user.register_user('Ϣʔβʔ໊', '[email protected]') }.to change { described_class.where(name: 'Ϣʔβʔ໊', email: '[email protected]').exists? }.from(false).to(true) end end end ॻ͘ςετ͸΍͸ΓͭͷΈ

Slide 23

Slide 23 text

࣮ߦ(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('Ϣʔβʔ໊', '[email protected]') }.to change { described_class.where(name: 'Ϣʔβʔ໊', email: '[email protected]').exists? }.from(false).to(true) expected `described_class.where(name: 'Ϣʔβʔ໊', email: '[email protected]').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ςʔϒϧʹσʔλΛ௥Ճ͍ͯ͠Δ͜ͱ ࣦഊ͢Δ͜ͱΛ֬ೝ

Slide 24

Slide 24 text

#register_userϝιουΛߋ৽ class User < ApplicationRecord def register_user(name, email) user = User.new user.name = name user.email = email user.save end end ςετΛ௨͢࠷খݶͷίʔυΛ࣮૷͢Δ͜ͱ ͱʹ͔͘ಈ͘ίʔυΛॻ͚͹͍͍

Slide 25

Slide 25 text

࣮ߦ(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 ੒ޭ͢Δ͜ͱΛ֬ೝ

Slide 26

Slide 26 text

ϦϑΝΫλϦϯά(Refactor) class User < ApplicationRecord def register_user(name, email) user = User.new(name: name, email: email) user.save end end ;ͭ͏ʹOFXͰύϥϝʔλ౉ͤ͹͍͍ΑͶ

Slide 27

Slide 27 text

࣮ߦ(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͕͋Ε͹ϦϑΝΫλϦϯά͠΍͍͢

Slide 28

Slide 28 text

TDD͸ιϑτ΢ΣΞςετٕ๏ͷ 1ͭͩͱޡղ͍ͯ͠Δਓ͕ଟ͍͚Ͳɺ ͜͜·Ͱ΍ͬͯΈΔͱTDDͷຊ࣭͸ ʮςετʯͰ͸ແ͍ͱ͍͏ࣄʹؾ෇͘͸ͣɻ ※࣮ࡍʹࣗ෼ͰखΛಈ͔ͯ͠ΈΔͱΑΓཧղग़དྷ·͢ɻ

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

.JOJUFTUͬͯͲ ͏ͳΜͰ͔͢ʁ ϫγͷए͍ࠒ ͸&YDFMʹςετ έʔεΛॻ͍͍ͯͬ ͯɾɾɾ ຊ൪؀ڥͷσʔ λͰͳ͍ͱ࠶ݱ͠ͳ ͍όά͸Ͳ͏΍ͬͯς ετͨ͠Βɾɾɾ ςετͷΧόϨο δͬͯԿΛ௒͍͑ͯ Δ΂͖ʁ ʮςετʯͷ࿩୊͹͔Γʂʂ

Slide 36

Slide 36 text

Կނ͜͏ͳͬͯ͠·͏ͷ͔ʁ TDD͸ςετٕ๏Ͱ͸ͳ͍ɻ ͱ͍͏࿩Λͨ͠௚ޙͳͷʹɻ ୭΋Զͷ࿩Λฉ͍ͯͳ͔ͬͨՄೳੑ͕ɾɾɾ

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

“TDD͸ɺςετͱ͍͏ݴ༿͕࣋ͭχϡΞϯεͷ໰୊ʹ௚໘͍ͯ͠·ͨ͠ɻςε τͱ͍͏୯ޠͱɺͦΕʹ·ͭΘΔޠኮΛ࢖͍ͬͯΔݶΓɺTDD͸ʮٕज़ऀ͕ɺ Ͳ͏࡞Δ͔ʯʹ࢖͏΋ͷͰ͋Δͱ͍͏ઌೖ؍ʹٯΒ͑ͣɺTDDͷਖ਼֬ͳཧղͱ ܒ໤ʹ͸ࢸΒͳ͍ͷͰ͸ͳ͍͔ͱ͍͏໰୊ҙࣝͰ͢ɻ” ൈਮ:: Kent Beck “Test-Driven Development: By Example” ෇࿥C TDDࢧ࣋೿ͷίϛϡχςΟͰ͜ͷ݅͸ٞ࿦ʹͳͬͨɻ ʮTDDʯͰ͸ବ໨ͰޠኮΛม͑ͳ͚Ε͹ͳΒͳ͍ɻ TDDͷTͷ෦෼ʹTestΛ࢖͍ͬͯΔݶΓɺTDD͕ਖ਼͘͠ཧղ ͞ΕΔ͜ͱ͸೉͍͠ɻ ͜͜ͰDanNorth͕ൃݟͨ͠ޠኮ͕ɺɺɺ TDDͱ͍͏ݴ༿๊͕͑Δ໰୊

Slide 39

Slide 39 text

Behavior ৼΔ෣͍

Slide 40

Slide 40 text

BDD

Slide 41

Slide 41 text

Behavior Driven Development ৼ෣ۦಈ։ൃ

Slide 42

Slide 42 text

ޠኮͷมߋͱRSpecͷ஀ੜ BTTFSUJPOˠFYQFDUBUJPO UFTUˠFYBNQMF UFTUDBTFˠFYBNQMFHSPVQ UFTUDMBTTˠTQFD w +#FIBWF +BWB ͕։ൃ͞Εͨ %BO/PSUI 5%%ˠ#%%͚ͩͰͳ͘ɺ ؒҧͬͨઌೖ؍Λ༩͑ͳ͍Α͏ ʹɺޠኮΛมߋ 5%%ͷࠒͱ͸ޠኮΛஔ͖׵͑ͨςετϑϨʔϜϫʔΫΛ࡞੒ w 34QFD 3VCZ ͷ஀ੜ΁ %BWF"TUFMTɺ"TMBL)FMMFT”Z

Slide 43

Slide 43 text

ޠኮ͕มΘΔͱࢥߟͷग़ൃ఺͕มΘΔ ςετ ςετΛॻ͜͏ ςετίʔυ Λॻ͘ ৼΔ෣͍ ৼΔ෣͍Λॻ͜͏ 4QFDΛॻ͘ #%%ͷαΠΫϧ΁ 5%%ͷ৔߹ #%%ͷ৔߹ ˞ॻ͍͍ͯΔϑΝΠϧ͸શ͘ಉ͡

Slide 44

Slide 44 text

BDDͷݱঢ় Behaviorͱ͍͏ޠኮͷൃݟʹΑΓɺ BDDͱ͍͏ޡղΛট͘ࣄͷͳ໊͍લ͕͍ͭͨ TDD͸ɺઌೖ؍Ͱޡղ͞ΕΔ͜ͱͳ͘ݱࡏ·Ͱ ਖ਼͘͠ೝࣝ͞Εͯීٴ͍ͯ͠·͢ɻ ΊͰͨ͠ΊͰͨ͠ɻ

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Կނ͜͏ͳͬͯ͠·ͬͨͷ͔ʁ • BDDͷܒ໤ظ(2003೥ʙ2011೥ࠒ?) • ܒ໤׆ಈ͕ඞཁͩͬͨͷͰ׆ൃͳٞ࿦͕ߦΘΕɺଟ͘ͷ৘ใ͕ྲྀ ௨͍ͯͨ͠ɻ • BDDͷݱࡏ(2018೥) • ࢖༻͍ͯ͠Δݴޠ͸ؔ܎ͳ͘ɺςετίʔυΛॻ͘؀ڥ͕طʹͦ ͜ʹ͋Δͷ͕౰ͨΓલɻ • ʮͳͥςετίʔυΛॻ͘ͷ͔ʁʯͳΜͯߟ͑ͳ͍ɻ ྺ࢙ɾܦҢ౳͸ফ໓ RSpecଞπʔϧ܊͕࢒ͬͨ

Slide 48

Slide 48 text

΋ͬͱਂ͘஌Γͨ͘ͳͬͨΒ ෇࿥CΛಡ΋͏

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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