Kaigi on Rails ( https://kaigionrails.org )の登壇資料です。
FactoryBotThe Right Way2020.10.3 Kaigi on Rails
View Slide
Self Introduction• GitHub: @toshimaru• Twitter: @toshimaru_e• Software Engineer at MedPeer Inc.• ࠷ۙͷٕज़తؔ৺• Vue.js, TypeScript, Ruby3ͷܕγεςϜ
࠾༻ใhttps://medpeer.co.jp/recruit/։ൃϒϩάhttps://tech.medpeer.co.jp/8FSF)JSJOH
FactoryBot The Right WayࠓςετσʔλੜϥΠϒϥϦɺfactory_bot ͷਖ਼͍͍͠ํʢRight Wayʣʹ͍͓ͭͯ͠·͢ɻ
Why?• ͜Ε·Ͱʮਖ਼͍͠RailsΞϓϦέʔγϣϯͷॻ͖ํʯʮਖ਼͍͠RSpecςετͷॻ͖ํʯଟ͘հ͞Ε͖ͯͨɻ• Ұํɺʮਖ਼͍͠ςετσʔλͷ࡞Γํʯ͋·Γٞ͞Εͯ͜ͳ͔ͬͨΑ͏ʹࢥ͑Δɻ
Rails ඪ४తςετߏϥΠϒϥϦ ςετର5FTUJOH'SBNFXPSL 34QFD NJOJUFTU3BJMT"QQMJDBUJPO .PEFM $POUSPMMFS 7JFX'JYUVSF 'BDUPSZ#PU 3BJMT'JYUVSFT .PEFM0CKFDU %BUBCBTF
Why Fixture Matters• ςετͷલఏͱͳΔঢ়ଶΛ࡞Γग़͢ͷ͕ Fixture• લఏ݅Λؒҧ͑ɺͦͷޙͷςετഁ͢Δ• Fixture Ͱਖ਼͍͠લఏঢ়ଶΛ࡞Γग़͢͜ͱ͕ॏཁ• ςετຖʹԿ܁Γฦ͠ݺΕΔ• ඇޮͳσʔλੜΛ͍ͯͨ͠߹ɺςετΛͤ͘͞ΔཁҼʹ
͢͜ͱ1. FactoryBot: The Right Way / The Good Way• Right Way: ެࣜυΩϡϝϯτ͔ΒͷൈਮɾҾ༻• Good Way: Right Way ͔Βநग़ͨ͠άουϓϥΫςΟε2. FactoryBot: The Wrong Way (Bad Way)• FactoryBotͷޡ͍ͬͨํɾྑ͘ͳ͍͍ํ
ൃදͷߏ✅ The Right Way The Good Way The Wrong WayԿ͕μϝʁ/Ͳ͏͢Δʁ
ϕϯνϚʔΫʹ͍ͭͯ• ϕϯνϚʔΫڥ• factory_bot v6.1.0 / Ruby v2.7• Database sqlite3 Λ༻ (In-Memory DB, File DB ͷ2ͭΛݕূ)• GitHub Actions ্ͰϕϯνΛΒͤΔ• benchmark-ips Ͱൺֱ• Repository: toshimaru/factory-bot-the-right-way
✅ The Right Wayfactory_bot gemಋೖRails ͷ߹:
✅ The Right Wayfactory_bot methodಋೖΫϥε໊Λলུͯ͠FactoryੜϝιουΛݺͼग़͢͜ͱ͕Ͱ͖ΔΑ͏ʹ:
✅ The Right WayFactoryఆٛ
The Wrong WayڊେσϑΥϧτσʔλ
The Wrong WayڊେσϑΥϧτσʔλ: Կ͕μϝʁ• ຊʹͦͷσʔλɺશ෦ඞཁͰ͔͢ʁ• ͦΕΛར༻͢ΔશͯͷςετέʔεͰ࠷খݶͷલఏঢ়ଶͷੜʹͳ͍ͬͯΔ͔ʁ• ແବͳσʔλੜʹͳ͍ͬͯͳ͍͔ʁ• ແବͳσʔλੜ• ؒҧͬͨલఏঢ়ଶΛ࡞Γग़͍ͯ͠Δ• ύϑΥʔϚϯεѱԽ
The Wrong WayڊେσϑΥϧτσʔλ: Ͳ͏͢Δʁ• ࠷খݶͷσʔληοτఆٛΛσϑΥϧτFactoryͱͯ͠ఆٛ͠·͠ΐ͏ʢref. Defining factories > Best practicesʣ
✅ The Right WayFactory ϑΝΠϧஔ• Լهύεʹఆٛ͞ΕͨFactoryϑΝΠϧࣗಈతʹϩʔυ͞ΕΔ• test/factories.rb• spec/factories.rb• test/factories"/*.rb• spec/factories"/*.rb
The Good WayFactory ϑΝΠϧஔ
✅ The Right WayFactory ੜ
The Wrong Wayແବcreate• build ͰࡁΉͱ͜ΖΛͳΜͰ͔ΜͰ create Λ࣮ͬͯϨίʔυΛੜͯ͠͠·͏͜ͱ
The Wrong Wayແବcreate: Կ͕μϝʁ• Ϣχοτςετͷඞཁ࠷ݶͳલఏ݅ʹͳ͍ͬͯͳ͍• DBʹσʔλ͕ create ͞Ε͍ͯΔ͜ͱඞཁ݅Ͱͳ͍• όϦσʔγϣϯͷςετͷ߹ɺvalid/invalidͳRubyΦϒδΣΫτͷঢ়ଶ͑͞࡞͍ͬͯΕΑ͍• SQL͕ΔɺύϑΥʔϚϯεѱԽ• ςετ୯ମͰʹͳΔ͜ͱ͕ͳ͍͕ɺνϦπϞͰςετΛͤ͘͞ΔཁҼʹͳΔ
The Wrong Wayແବcreate: Կ͕μϝʁ• create, build ͦΕͧΕΛͬͨ߹ͷSQLൺֱɿ
The Wrong Wayແବcreate: Ͳ͏͢Δʁ• buildΛ͍·͠ΐ͏
The Wrong Wayແବcreate: ϕϯνϚʔΫ• In-Memory DB• File DB
The Good Waybuild_stubbed ׆༻• Լهͷ߹ͷςετ• ʮcreated_at build ͡Όੜ͞Εͳ͍ͧ ʯ
The Good Waybuild_stubbed ׆༻• build_stubbed Λ׆༻͢Εɺελϒ͞Εͨid, timestampͱͱʹΦϒδΣΫτ͕ੜ͞ΕΔ
✅ The Right WayTrait (1)
✅ The Right WayTrait (2)
The Wrong WayToo Many Traits• ྫ֎తͳɺڥքͳͲΛtraitͰΕͳ͘શ෦ఆٛ͠Α͏ͱ͢Δ͜ͱ
The Wrong WayToo Many Traits: Կ͕μϝʁ• traitఆٛ രൃ• Fat Model ͳΒ͵ Fat Factory ͷग़དྷ্͕Γ• Fat Factory• ຊʹඞཁͳ trait ͕ݟ͚ͭʹ͘͘ͳΔ• ͳΜͰ͔ΜͰશͯͷύλʔϯΛ trait ʹدͤͯॻ͖ͨ͘ͳͬͪΌ͏පؾ͕ൃ͢Δ
The Wrong WayToo Many Traits: Ͳ͏͢Δʁ• ͍ճͤΔ൚༻తͳৼΔ͍ͷΈΛ trait ʹఆٛ͢Δ• ྫ֎తͳݸผͷςετʹدͤΔ• ྫ: ϞσϧͷόϦσʔγϣϯςετ
The Wrong WayDRY͡Όͳ͍traits• DRY (Don't repeat yourself) Ͱͳ͍traitɺॏෳͨ͠ trait ͕ଟ͘ఆٛ͞Ε͍ͯΔঢ়ଶͷ͜ͱ
The Wrong WayDRY͡Όͳ͍traits: Կ͕μϝʁ• traitఆٛ Έ߹Θͤരൃ • Fat Model ͳΒ͵ Fat Factory ͷग़དྷ্͕Γʢref. Too Many Traitsʣ
The Wrong WayDRY͡Όͳ͍traits: Ͳ͏͢Δʁ• ಈ࡞͢ΔσϑΥϧτͷঢ়ଶΛ Factory ͱͯ͠γϯϓϧʹఆٛ͠ɺͦΕʹಛघͳঢ়ଶΛఆٛ͢ΔtraitΛॏͶ͍ͯ͘
The Wrong WayDRY͡Όͳ͍traits: Ͳ͏͢Δʁ•আ͞Ε͍ͯΔAdminϢʔβʔ࡞ ߏஙύλʔϯɿ
✅ The Right Waysequence• sequence Λ͏͜ͱͰσʔλʹγʔέϯγϟϧͳφϯόϦϯά͕Մೳʹ
The Wrong Wayಠࣗsequence id• DBͰ࠾൪͞ΕΔidΛಠࣗͷidͰΦʔόʔϥΠυͯ͠͠·͏͜ͱ
The Wrong Wayಠࣗsequence id: Կ͕μϝʁ• Ϩίʔυ࡞ͤͣͱid࠾൪͕ߦΘΕΔ• ࣮ࡍͷDBͷڍಈͱҟͳΔͷͰɺϦΞϧͳςετʹͳΒͳ͍
The Wrong Wayಠࣗsequence id: Ͳ͏͢Δʁ• ID࠾൪DBʹͤ·͠ΐ͏• Stub͞Εͨ id ͕ཉ͍͠ͷͰ͋Εɺ build_stubbed Λར༻͠·͠ΐ͏ʢref. build_stubbed ׆༻ʣ
The Wrong Wayಉ͡ͷςετ
The Wrong Wayಉ͡ͷςετ: Կ͕μϝʁ• name ͕ಉ͡Λੜ͍ͯ͠ΔͷͰɺuser1.name ͕ user2.name Ͱ user3.name Ͱςετ͕௨ͬͯ͠·͏
The Wrong Wayಉ͡ͷςετ: Ͳ͏͢Δʁ• sequence ΛͬͯϢχʔΫੑͷ͋ΔσʔλΛੜ͢Δ• ϦΞϧϫʔϧυʹ͍ۙσʔλΛ faker Λͬͯੜ͢Δ
✅ The Right Waybuild_list, create_list• build_list: ࢦఆճ build ͨ͠ίϨΫγϣϯΛฦ͢• create_list: ࢦఆճ create ͨ͠ίϨΫγϣϯΛฦ͢
The Wrong Wayແବlistੜ• ෆඞཁʹ create_list ͯ͠ແବͳσʔλੜΛߦ͏͜ͱ
The Wrong Wayແବlistੜ: Կ͕μϝʁ• ͦͷσʔλɺશ෦ඞཁͰ͔͢ʁ (ref. ڊେσϑΥϧτσʔλ)• ແବͳσʔλੜʹͳ͍ͬͯͳ͍͔ʁ
The Wrong Wayແବlistੜ: Ͳ͏͢Δʁ• transient + evaluator ͷػೳΛ͍ؔ࿈ઌϨίʔυੜΛίϯτϩʔϧ͢Δ• ຊʹඞཁͳ͚ͩࢦఆͯ͠Ϩίʔυੜ͢ΔΑ͏ʹ͢Δ
✅ The Right WayAssociation ఆٛ↓ ্ड़ͷ post Factory Լهͱಉҙ ↓
The Wrong WayAlways Create Association• association ઌΛ create Ͱ࡞ͯ͠͠·͏͜ͱ
The Wrong WayAlways Create Association: Կ͕μϝʁ• build ͨ͠߹Ͱৗʹ createʢϨίʔυੜʣ͕͏
The Wrong WayAlways Create Association: Ͳ͏͢Δʁ• ૉʹ association ఆٛ͢Δ
The Wrong WayAlways Create Association: ϕϯνϚʔΫ• In-Memory DB• File DB
✅ The Right WayFactoryBot.lint• factory_bot ެ͕ࣜఏڙ͢ΔLintπʔϧ• FYI: rubocop-rspec ʹ FactoryBot ༻ͷϧʔϧಉࠝ͞Ε͍ͯΔ• ref. RuboCop"::Cop"::RSpec"::FactoryBot
✅ The Right WayFactoryBot.lint: how it works• ఆٛ͞Εͨ Factory ΛҰ௨Γ create ͯ͠ɺinvalid ͳ Factory ఆٛΛݕ͢Δ• traits: true ΦϓγϣϯͰ trait ؚΊͯݕࠪ͢Δ
• rakeλεΫԽͯ͠ଞLintπʔϧʢrubocopʣͱಉ༷ʹCIͷλεΫͷ̍ͭͱ͓ͯͤͯ͘͠ The Good WayFactoryBot.lint: rakeλεΫԽ
✅ FactoryBot The Right Way·ͱΊ• ਖ਼͍͠લఏঢ়ଶΛਖ਼͘͠࡞Δ• ؆୯ʹσʔλఆٛɾϨίʔυੜͰ͖ͯ͠·͏ނʹɺ؆୯ʹແବσʔλΛ࡞Γग़͍͢͠• ԼهΛҙࣝͯ͠ facotry_bot Λ͍͜ͳͦ͏• Factory ͷσϑΥϧτఆٛϛχϚϧͳσʔληοτʹͳ͍ͬͯΔ͔ʁ• ֤ʑͷςετέʔεͰ͍ͬͯΔ Factory ࠷ݶͷલఏঢ়ଶΛ࡞Γग़͍ͤͯΔ͔ʁ
HappyTestingLife!
Tips: FactoryGirl→FactoryBot• 2008 FactoryGirlੜ• 2017 FactoryGirl͔ΒFactoryBotʹϦωʔϜ• ref. Project Naming History⾠ OSS ͷ Naming ؾΛ͚ͭΑ͏ʂ
Tips: ςετσʔλͷϞοΫ/ελϒʹ͍ͭͯ“ϞοΫ/ελϒʹΑͬͯςετίʔυͷ࣮ߦεϐʔυ͕ૣ͘ͳΓςετͷੑߴ·ΔҰํɺϞοΫ/ελϒʻࣗͷໝɾئ͕࡞Γग़ͨ͠ৼΔ͍ʼʹͳΔͷͰɺ࣮ࡍͷৼΔ͍ͱҟͳΔͱ͍͏ϦεΫΛሃΉɻ·ͨϞοΫ/ελϒΛ࡞Δ͜ͱͰɺϝϯςϯφϯεରͱͳΔίʔυͷྔɾॏෳ͕ଟ͘ͳΔɻϩʔΧϧڥͰ࠶ݱͰ͖ΔRDBKVSՄೳͳݶΓຊΛ͏ɻ”ʢfukabori.fm 13. ϖΞϓϩςετͷٙͱ͔ɺιϑτΣΞΤϯδχΞͷҭͱ͔ ͷtwada͞ΜͷൃݴΑΓཁʣ
ࢀߟจݙ• ެࣜυΩϡϝϯτ• thoughtbot/factory_bot Getting Started• ϕϯνϚʔΫιʔείʔυ• toshimaru/factory-bot-the-right-way• ͦͷଞ• Rails Ξϯνύλʔϯ - Ḋͼ͍ͭͨϑΝΫτϦʔ (factory_girl) - ΞδϟΠϧSEͷ༕ᓔ