Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
約9000個の自動テストの 時間を50分->10分に短縮 Flakyテストを1%以下に抑えた話
Search
hatsu
October 25, 2024
Programming
24
13k
約9000個の自動テストの 時間を50分->10分に短縮 Flakyテストを1%以下に抑えた話
hatsu
October 25, 2024
Tweet
Share
More Decks by hatsu
See All by hatsu
Just a Rails Patch Update
hatsu38
2
480
Dive into MaintenanceTasks
hatsu38
1
92
GitHub Actions is Fun
hatsu38
1
110
Other Decks in Programming
See All in Programming
Arm移行タイムアタック
qnighy
0
330
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
120
Click-free releases & the making of a CLI app
oheyadam
2
120
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
2k
Remix on Hono on Cloudflare Workers
yusukebe
1
290
Ethereum_.pdf
nekomatu
0
460
ECS Service Connectのこれまでのアップデートと今後のRoadmapを見てみる
tkikuc
2
250
Macとオーディオ再生 2024/11/02
yusukeito
0
370
ふかぼれ!CSSセレクターモジュール / Fukabore! CSS Selectors Module
petamoriken
0
150
Jakarta EE meets AI
ivargrimstad
0
580
Figma Dev Modeで変わる!Flutterの開発体験
watanave
0
130
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
Docker and Python
trallard
40
3.1k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Side Projects
sachag
452
42k
Code Review Best Practice
trishagee
64
17k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
A Philosophy of Restraint
colly
203
16k
Rails Girls Zürich Keynote
gr2m
94
13k
Visualization
eitanlees
145
15k
Transcript
9000ݸͷࣗಈςετͷ ࣌ؒΛ50->10ʹॖ FlakyςετΛ1%ҎԼʹ͑ͨ Kaigi on Rails 2024 @hatsu_38 2024/10/26
εϥΠυ1ຕʹ͖ͭ6ඵͷϖʔεͰਐ· ͳ͍ͱؒʹ߹͍ͳ͍ܭࢉʹͳΓ·͠ ͨɻͦͷϖʔεͰਐΉ͜ͱྃ͝ঝͩ͘ ͍͞🙏
ࣗݾհ • Twitter: @hatsu_38 • GitHub: @hatsu38 • SHE Inc.
• Rubyྺ 5 = ΤϯδχΞྺ • React.js / TypeScript / GitHub Actions • Ruby͕Ұ൪͖
CIͰࣗಈςετ ࣮ߦ͍ͯ͠·͔͢ʁ🙋
ࣗಈςετ 10Ҏ্͔͔͍ͬͯ·͔͢ʁ🙋
Initial Commit2017 ฐࣾͷ͜ͱ🏢
ٕज़ελοΫ🤖 • Backend: Ruby on Rails, GraphQL, Sidekiq • Frontend:
React.js, TypeScript, Next.js • CI: GitHub Actions • Infrastructure: Kubenetes ฐࣾͷ͜ͱ🏢 7
2023ͷࣗಈςετͷঢ়گ🔍 ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍
Model / Controller / Requests / System Spec, etc. ςετ
7,803 case 2023.05.22 34QFD $BQZCBSBΛར༻ ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍 Code to Test Ratio: 1:4.3 Test Coverage: 89%
Model / Controller / Requests / System Spec, etc. ςετ࣌ؒ
ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍 $*͕௨ΔͷʹҎ্🫠
Flakyͳςετࢁ💥 ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍 ࣮ߦ݁Ռ͕ ෆ҆ఆͳςετ
ཧͷCIͷ࣌ؒ10Ҏɺ Έ͍ͨͳจষΛҾ༻͢Δ ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍
ཧͷCIͷ࣌ؒ10Ҏɺ Έ͍ͨͳจষΛҾ༻͢Δ $*ͷεϐʔυେͰ͢ɻ ཧҎɺ͘ͱҎʹྃͤ͞·͠ΐ͏ɻ ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍
ཧͷCIͷ࣌ؒ10Ҏɺ Έ͍ͨͳจষΛҾ༻͢Δ $*ͷεϐʔυେͰ͢ɻ ཧҎɺ͘ͱҎʹྃͤ͞·͠ΐ͏ɻ ϑϨʔΩʔςετͷ͕͖͍͠Λ͑Δͱɺ ςετશମ͕৴པ͞Εͳ͘ͳΔͷͰ͢ɻͦͷ͖͍͠Ͱ͢ɻ ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍
վળ͠Α͏🛠⚙ ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍
ςετ DBTF $*ͷ࣌ؒ ฒྻ$PSF 'MBLZςετ ݸ
͘Β͍ͷ֬Ͱ$*͕མͪΔ (JU)VC"DUJPOTͷஈ ฐࣾͷ͜ͱ - 2023ͷςετͷঢ়گ🔍 2023ͷςετͷঢ়گ🔍
͜Ε͔Βɺͬͨ͜ͱΛ ͨ͘͞Μհ͍͖ͯ͠·͢💡
ࣗࣾͰ͑ͦ͏ͳ5JQT ෦͜Μͳ࣮Ͱಈ͍͍ͯΔΜͩ ͬͯൃݟ͕1ͭ͋Εྑ͍ͳͱ💯💡
ͭͷ՝💥 • ςετͷ͕͍࣌ؒ🐢 • ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ʢগ͠3VCZ͔Βઢʣ • Flakyͳςετ͕ଟ͍💫
ͭͷ՝💥 • ςετͷ͕͍࣌ؒ🐢 • ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ʢগ͠3VCZ͔Βઢʣ • Flakyͳςετ͕ଟ͍💫
• CapybaraͷػೳʹͤͯSleepΛআ • LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ ςετͷ͕͍࣌ؒ🐢 21 ςετͷ͕͍࣌ؒ🐢
• CapybaraͷػೳʹͤͯSleepΛআ • LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ ςετͷ͕͍࣌ؒ🐢 22 ςετͷ͕͍࣌ؒ🐢
Sleep͕59Օॴ͋ͬͨ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ
Sleep͕ΘΕ͍ͯΔྫ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ ϑΥʔϜೖྗͯ͠ɺอଘ͢ΔϘλϯԡͨ͠Βɺ
Sleep͕ΘΕ͍ͯΔྫ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ
have_text(“hoge”)ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ
have_text(“hoge”)ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ
have_text(“hoge”)ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ EFGBVMU@NBY@XBJU@UJNF σϑΥϧτ ඵؒ୳͠ଓ͚Δඵͷઃఆ ͜ͷඵͷؒɺςΩετzIPQFzΛ୳ͯ͘͠ΕΔ
have_text(“hoge”)ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ EFGBVMU@SFUSZ@JOUFSWBM σϑΥϧτ ඵςΩετzIPHFzΛ܁Γฦ͠୳ִؒ͢ EFGBVMU@NBY@XBJU@UJNF σϑΥϧτ ඵؒ୳͠ଓ͚Δඵͷઃఆ
͜ͷඵͷؒɺςΩετzIPQFzΛ୳ͯ͘͠ΕΔ
have_text(“hoge”)ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ ͜Ε͕retryͰ܁Γฦ͠ಈ͘ EFGBVMU@NBY@XBJU@UJNF σϑΥϧτ ඵؒ୳͠ଓ͚Δඵͷઃఆ ͜ͷඵͷؒɺςΩετzIPQFzΛ୳ͯ͘͠ΕΔ EFGBVMU@SFUSZ@JOUFSWBM
σϑΥϧτ ඵςΩετzIPHFzΛ܁Γฦ͠୳ִؒ͢
Sleep͕59 30Օॴʹݮͬͨ✨ CapybaraͷػೳʹͤͯSleepΛআ
Capybaraͷػೳʹͤͯ SleepΛআ ςετͷ͕͍࣌ؒ🐢 - CapybaraͷػೳʹͤͯSleepΛআ खܰ͞: ˒˒˒˒˒ ޮՌ: ˒˒˒ˑˑ
• CapybaraͷػೳʹͤͯSleepΛআ • LoadingΛಈతʹͭHelperΛ࡞ͬͯSleepΛআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ ςετͷ͕͍࣌ؒ🐢 33 ςετͷ͕͍࣌ؒ🐢
Sleep͕30Օॴ͋ͬͨ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ
Sleep͕ΘΕ͍ͯΔྫ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ > default_max_wait_time
LoadingΞΠίϯ͕ফ͑ΔͷΛͭHelperΛ࡞ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ ಈతʹ-PBEJOHΞΠίϯ͕ফ͔͑ͨͲ͏͔ ܁Γฦ֬͠ೝ͢Δ
LoadingΞΠίϯ͕ফ͑ΔͷΛͭHelperΛ࡞ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ ಈతʹ-PBEJOHΞΠίϯ͕ফ͔͑ͨͲ͏͔ ܁Γฦ֬͠ೝ͢Δ ͜͜ʹHTMLͷSelectorΛࢦఆ
LoadingΞΠίϯ͕ফ͑ΔͷΛͭHelperΛར༻ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ $BQZCBSBͷEFGBVMU@NBY@XBJU@UJNFͰ-PBEJOH͕ ऴΘΒͳ͍߹ʹར༻
Sleep͕59 30 13Օॴʹݮͬͨ✨ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ
LoadingΛಈతʹͭHelperΛ ࡞ͬͯSleepΛআ ςετͷ͕͍࣌ؒ🐢 - LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ खܰ͞: ˒˒˒ˑˑ ޮՌ: ˒˒˒˒ˑ
• CapybaraͷػೳʹͤͯSleepআ • LoadingΛಈతʹͭHelperΛ࡞ͬͯSleepআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ ςετͷ͕͍࣌ؒ🐢 41 ςετͷ͕͍࣌ؒ🐢
σʔλ࡞͕25,550݅ - 35݅ͷςετ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ →ςετ࣌ؒ1m24sͷ͏ͪ1m4s͕σʔλੜ test-prof gemͰௐࠪ
σʔλ࡞͕25,550݅ - 35݅ͷςετ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ → Seedσʔλͷ࡞Λߦ͏εΫϦϓτ 1Ͱ675݅ͷσʔλΛ࡞͢Δ JSC
NBJO
Seedσʔλ࡞εΫϦϓτ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ ଞͷςετͰ͍·Θͤͦ͏💡
σʔλ࡞͕25,550݅ - 35݅ͷςετ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ before_allͰSeedσʔλΛ͍ճ͢
before_all { Fixtures.setup }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ
before_all { Fixtures.setup }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ ςετάϧʔϓશମʹରͯ͠
before_all { Fixtures.setup }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ ςετάϧʔϓશମʹରͯ͠ τϥϯβΫγϣϯΛுͬͯ ͦͷதͰblockΛݺͼग़͢
before_all { Fixtures.setup }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ ςετάϧʔϓશମʹରͯ͠ τϥϯβΫγϣϯΛுͬͯ ͦͷதͰblockΛݺͼग़͢
ςετάϧʔϓͷςετ͕ऴΘͬͨΒ Rollback͢Δ
σʔλ࡞͕25,550݅ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ →ςετ࣌ؒ1m24sͷ͏ͪ1m4s͕σʔλੜ(ςετέʔε35έʔε) test-prof gemͰௐࠪ
σʔλ࡞͕25,550 2,600݅ʹݮͬͨ✨ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ ςετ࣌ؒ1m24s->40sʹॖ test-prof gemͰௐࠪ
test-profͷbefore_allΛͬͯ σʔλ࡞Λলུ ςετͷ͕͍࣌ؒ🐢 - test-profͷbefore_allΛͬͯσʔλ࡞Λলུ खܰ͞: ˒˒˒˒ˑ ޮՌ: ˒˒˒˒˒
• CapybaraͷػೳʹͤͯSleepআ • LoadingΛಈతʹͭHelperΛ࡞ͬͯSleepআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ ςετͷ͕͍࣌ؒ🐢 53 ςετͷ͕͍࣌ؒ🐢
σʔλ࡞͕37,530݅ - 675݅ͷςετ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ →ςετ࣌ؒ2m50sͷ͏ͪ2m1s͕σʔλੜ test-prof gemͰௐࠪ
σʔλ࡞͕37,530݅ - 675݅ͷςετ ྫ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ
σʔλ࡞͕37,530݅ - 675݅ͷςετ ྫ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ →ςετͷͨͼʹݺΕΔ
σʔλ࡞͕37,530݅ - 675݅ͷςετ ྫ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ ͕ɺຖ࡞Γ͞ͳͯ͘ಉ͡ΠϯελϯεΛ͍·ͤΔม💡 →ςετͷͨͼʹݺΕΔ
letΛଞͷςετͰ͍ճ͢ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ
let_it_be(:admin) { create(:user) }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ
let_it_be(:admin) { create(:user) }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ proc { @😸admin
= create(:user) }
let_it_be(:admin) { create(:user) }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ proc { @😸admin
= create(:user) } before_all { @😸admin = create(:user) }
let_it_be(:admin) { create(:user) }ͰԿ͕ى͖͍ͯΔ͔ʁ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ proc { @😸admin
= create(:user) } before_all { @😸admin = create(:user) } let(:admin) { @😸admin } (`@😸admin` before_allͰ࡞ࡁΈ)
σʔλ࡞͕37,530݅ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ →ςετ࣌ؒ2m50sͷ͏ͪ2m1s͕σʔλੜ test-prof gemͰௐࠪ
σʔλ࡞͕37,530 4,970݅ʹݮͬͨ✨ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ ςετ࣌ؒ2m50s->37s test-prof gemͰௐࠪ
test-profͷlet_it_beΛͬͯ σʔλ࡞Λলུ ςετͷ͕͍࣌ؒ🐢 - test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ खܰ͞: ˒˒˒˒ˑ ޮՌ: ˒˒˒˒ˑ
• CapybaraͷػೳʹͤͯSleepΛআ • LoadingΛಈతʹͭHelperΛ࡞ͬͯSleepΛআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳ͋Ε͜Ε ςετͷ͕͍࣌ؒ🐢 66 ςετͷ͕͍࣌ؒ🐢
parallel_testsͱʁ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ $16@ .ݸͷ ςετϑΝΠϧ $16@ /ݸͷ ςετϑΝΠϧ
ɾɾɾ $16@9 ,ݸͷ ςετϑΝΠϧ CPUݸʹςετϑΝΠϧΛׂͯ͠ɺ ςετΛฒྻʹ࣮ߦͤ͞Δ💡
ޮͷѱׂ͍ - 1,000s ͔͔Δ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ user_spec.rb ͕ංେԽ
ޮͷѱׂ͍ - 1,000s ͔͔Δ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ $16T $16 T
ޮͷྑׂ͍ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ T͔͔ΔςετϑΝΠϧΛͭʹׂ $16 T
ޮͷྑׂ͍ - 600sͰऴΘΔ✨ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ $16T $16T
ޮͷྑׂ͍ - ࣮ྫ parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ Before After
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘͯ͠ྻΛ࡞ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 73
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 74
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘͯ͠ྻΛ࡞ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 75 [ςετ໊, ςετϑΝΠϧByte]
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 76 ͜ͷྻΛϑΝΠϧαΠζͷ߱ॱʹSort
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 77 $16 $16 $16 $16
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 78 $16 $16 $16 $16 ,ݸͷ ςετϑΝΠϧ .ݸͷ ςετϑΝΠϧ /ݸͷ ςετϑΝΠϧ -ݸͷ ςετϑΝΠϧ
parallel_testsͰԿ͕ى͖ͯΔʁ(ྫ: fi le size sort) 1. CPUίΞΛऔಘͯ͠ 2. ςετରͷϑΝΠϧͷϑΝΠϧαΠζ(byte)Λऔಘ 3.
ϑΝΠϧαΠζͷେ͖͍ॱʹฒͼସ͑ͯ 4. CPUݸͷάϧʔϓΛ࡞ͬͯ 5. ϑΝΠϧαΠζͷେ͖͍ॱʹɺ߹ܭϑΝΠϧαΠζͷ࠷খ͍͞ά ϧʔϓʹɺϑΝΠϧΛՃΛ܁Γฦͯ͠άϧʔϓ࡞ 6. ֤$16ͰςετΛ࣮ߦ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ 79
parallel_testsͷฒྻ࣮ߦΛ׆͔͢ ͨΊʹϑΝΠϧׂ ςετͷ͕͍࣌ؒ🐢 - parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ खܰ͞: ˒˒˒˒ˑ ޮՌ: ˒˒˒˒ˑ
• CapybaraͷػೳʹͤͯSleepΛআ • LoadingΛಈతʹͭHelperΛ࡞ͬͯSleepΛআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ • parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ
• ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ ςετͷ͕͍࣌ؒ🐢 81 ςετͷ͕͍࣌ؒ🐢
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 82
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 83 खܰ͞: ˒˒˒˒ˑ ޮՌ: ˒˒ˑˑˑ
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 84 Bad Good खܰ͞: ˒˒˒ˑˑ ޮՌ: ˒˒˒ˑˑ
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 85 खܰ͞: ˒˒˒ˑˑ ޮՌ: ˒˒˒ˑˑ
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 86 खܰ͞: ˒˒ˑˑˑ ޮՌ: ˒˒ˑˑˑ
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 87 खܰ͞: ˒ˑˑˑˑ ޮՌ: ˒˒˒ˑˑ
ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do ~
endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμογϡϘʔυԽ ςετͷ͕͍࣌ؒ🐢 - ͦͷଞɺࡉ͔ͳςετ࣌ؒॖͷͨΊͷࢪࡦ 88 खܰ͞: ˒ˑˑˑˑ ޮՌ: ˒˒ˑˑˑ
CIͷ͕࣌ؒ54->23✨ ςετͷ͕͍࣌ؒ🐢 5FTU NT #VJME NT 3FQPSU T
લઓऴྃ🍻 ʢͨͿΜ12͘Β͍ܦաதʣ
CIͷ͕࣌ؒ54->23✨ ςετͷ͕͍࣌ؒ🐢 5FTU NT #VJME NT 3FQPSU T
CIͷ͕࣌ؒ54->23✨ ςετͷ͕͍࣌ؒ🐢 5FTU NT #VJME NT 3FQPSU T 23🤔
ͭͷ՝💥 • ςετͷ͕͍࣌ؒ🐢 • ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ʢগ͠3VCZ͔Βઢʣ • Flakyͳςετ͕ଟ͍💫
• Next.js × TypeScript ͰϑϩϯτΤϯυಈ͍͍ͯΔ • Adminը໘ͱUserը໘ͦΕͧΕ͋ΔɻϦϙδτϦ1ͭɻ • ຖճ#VJME͚ͩͰ10Ҏ্͔͔͍ͬͯΔ •
ฒྻ࣮ߦͱ͔͕ҙຯͳ͍ɻ͓ۚͰԥΕͳ͍ɻ • ςετલʹ#VJME͢Δඞཁ͕͋ΔͷͰલςετ͕͜ͷ࣮ߦ࣌ؒʹґଘ ͍ͯ͠Δ ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 94 ςετલͷBuild
Next.jsެࣜαΠτΑΓ📗 ςετલͷ#VJMEͷ͕͍࣌ؒ🥱
Next.jsެࣜαΠτΑΓ📗 ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ϏϧυͷύϑΥʔϚϯεΛ্ͤ͞ΔͨΊʹɺ /FYUKTϏϧυؒͰڞ༗͞ΕΔΩϟογϡΛOFYUDBDIFʹอଘ͠·͢ɻ ܧଓతΠϯςάϨʔγϣϯ $* ڥͰ͜ͷΩϟογϡΛ׆༻͢Δʹɺ ϏϧυؒͰΩϟογϡΛਖ਼͘͠อ࣋͢ΔΑ͏ʹɺ$*ϫʔΫϑϩʔΛߏ͢Δඞཁ ͕͋Γ·͢ɻ
Next.jsެࣜαΠτΑΓ📗 ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ϏϧυͷύϑΥʔϚϯεΛ্ͤ͞ΔͨΊʹɺ /FYUKTϏϧυؒͰڞ༗͞ΕΔΩϟογϡΛOFYUDBDIFʹอଘ͠·͢ɻ ܧଓతΠϯςάϨʔγϣϯ $* ڥͰ͜ͷΩϟογϡΛ׆༻͢Δʹɺ ϏϧυؒͰΩϟογϡΛਖ਼͘͠อ࣋͢ΔΑ͏ʹɺ$*ϫʔΫϑϩʔΛߏ͢Δඞཁ ͕͋Γ·͢ɻ .next/cacheΛΩϟογϡͯ͠Build࣌ʹ͍ճ͢
10 -> 5✨ खܰ͞: ˒˒˒ˑˑ ޮՌ: ˒˒˒˒˒
Next.jsެࣜαΠτΑΓ📗 ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ϏϧυͷύϑΥʔϚϯεΛ্ͤ͞ΔͨΊʹɺ /FYUKTϏϧυؒͰڞ༗͞ΕΔΩϟογϡΛOFYUDBDIFʹอଘ͠·͢ɻ ܧଓతΠϯςάϨʔγϣϯ $* ڥͰ͜ͷΩϟογϡΛ׆༻͢Δʹɺ ϏϧυؒͰΩϟογϡΛਖ਼͘͠อ࣋͢ΔΑ͏ʹɺ$*ϫʔΫϑϩʔΛߏ͢Δඞཁ ͕͋Γ·͢ɻ มߋͳ͍ͱ͖Buildͤͣʹɺ
Build݁ՌͷΩϟογϡΛ͍ճ͢ खܰ͞: ˒˒˒ˑˑ ޮՌ: ˒˒˒˒˒ 10 -> 5->34ඵ✨
Build͕࣌ؒ10->34ඵ✨ ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 Ϣʔβʔը໘ "ENJOը໘ ZBSOMPDLʹมߋ͕͋Δ߹ ඵ ඵ ZBSOMPDLʹมߋͳ͍͕ɺ ϑϩϯτͷίʔυʹมߋ͕͋Δ߹ ඵ
ඵ Ұมߋ͕ͳ͍߹ ඵ✨ ඵ✨
CIͷ͕࣌ؒ54->23 10✨ ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 5FTU NT #VJME T 3FQPSU T
தฤऴྃ🍻 ʢͨͿΜ13͘Β͍ܦաதʣ
ͭͷ՝💥 • ςετͷ͕͍࣌ؒ🐢 • ςετલͷ#VJMEͷ͕͍࣌ؒ🥱 ʢগ͠3VCZ͔Βઢʣ • Flakyͳςετ͕ଟ͍💫
Flakyͳςετͱʁ • ࣮ߦ݁Ռ͕ෆ҆ఆͳςετͷ͜ͱ • Flakyͳςετ͕গͳ͘ͱ30ݸҎ্͋ͬͨ • 5%ͷ֬ͰམͪΔෆ҆ఆͳςετ͕30ݸ͋Δͱɺςετ͕શͯύε ͢Δ֬21.5% Flakyͳςετ͕ଟ͍💫 103
Flakyͳςετ͕ଟ͍💫 • ࣮ߦ݁Ռ͕ෆ҆ఆͳςετͷ͜ͱ • Flakyͳςετ͕গͳ͘ͱ30ݸҎ্͋ͬͨ • 5%ͷ֬ͰམͪΔෆ҆ఆͳςετ͕30ݸ͋Δͱɺςετ͕શͯύε ͢Δ֬21.5% Flakyͳςετ͕ଟ͍💫 104
ɾࣦഊɺۉҰͰͳ͍ ɾࣦഊ͕͍ͷɺӅΕͯฆΕͯͨΓ͢Δ ɾࣦഊ͕ߴ͍ςετ͔Β͍ͯ͘͠ͱྑ͍
Flakyͳςετͷ͖߹͍ํ Flakyͳςετ͕ଟ͍💫 5FTU NT #VJME T 3FQPSU T ಓʹ͢💪
ಓʹ͢ࡍͷ େมͩͬͨ͜ͱɺͨ͜͠ͱ🛠🤖 Flakyͳςετ͕ଟ͍💫
ಓʹ͢ࡍʹେมͩͬͨ͜ͱ • CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ • CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ • FlakyΛθϩʹ͖͠Εͳ͍ Flakyͳςετ͕ଟ͍💫 107
ಓʹ͢ࡍʹେมͩͬͨ͜ͱ • CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ • CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ • FlakyΛθϩʹ͖͠Εͳ͍ Flakyͳςετ͕ଟ͍💫 108
E2E͕CI্ͰFailͨ͠Β…ϩάΛ֬ೝ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ ໘😮💨
E2E͕CI্ͰFailͨ͠Β…εΫϦʔϯγϣοτΛ֬ೝ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ ໘😮💨
Allure ReportΛಋೖ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘
• ςετ݁ՌΛྑ͍ײ͡ʹϨϙʔτ͢Δͭ • ςετͷ • ΧόϨοδ • ςετ࣌ؒ • ςετ݁Ռཤྺ
• εΫγϣͱ͔ඥ͚ΒΕΔ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ 112 Allure Reportͱʁ
• bundle exec rspec --format AllureRspecFormatter • ςετͷใΛKTPOʹग़ྗ • allure
generate allure_results/* -o tmp/allure_report • ςετ݁ՌΛ)5.-ʹม • ϓϧϦΫΤετຖʹςετ݁Ռͷ)5.-Λ7FSDFMʹσϓϩΠ • ςετࣦഊ࣌ʹ7FSDFMͷ63-Λ#PU͕ίϝϯτͰڭ͑ͯ͘ΕΔ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ 113 Allure Report͓ΒͤBotΛ࡞
• bundle exec rspec --format AllureRspecFormatter • ςετͷใΛKTPOʹग़ྗ • allure
generate allure_results/* -o tmp/allure_report • ςετ݁ՌΛ)5.-ʹม • ϓϧϦΫΤετຖʹςετ݁Ռͷ)5.-Λ7FSDFMʹσϓϩΠ • ςετࣦഊ࣌ʹ7FSDFMͷ63-Λ#PU͕ίϝϯτͰڭ͑ͯ͘ΕΔ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ 114 Allure ReportΛಋೖ
• bundle exec rspec --format AllureRspecFormatter • ςετͷใΛKTPOʹग़ྗ • allure
generate allure_results/* -o tmp/allure_report • ςετ݁ՌΛ)5.-ʹม • ϓϧϦΫΤετຖʹςετ݁Ռͷ)5.-Λ7FSDFMʹσϓϩΠ • ςετࣦഊ࣌ʹ7FSDFMͷ63-Λ#PU͕ίϝϯτͰڭ͑ͯ͘ΕΔ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ 115 Allure ReportΛಋೖ
• bundle exec rspec --format AllureRspecFormatter • ςετͷใΛKTPOʹग़ྗ • allure
generate allure_results/* -o tmp/allure_report • ςετ݁ՌΛ)5.-ʹม • ϓϧϦΫΤετຖʹςετ݁Ռͷ)5.-Λ7FSDFMʹσϓϩΠ • ςετࣦഊ࣌ʹ7FSDFMͷ63-Λ#PU͕ίϝϯτͰڭ͑ͯ͘ΕΔ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ 116 Allure ReportΛಋೖ
• bundle exec rspec --format AllureRspecFormatter • ςετͷใΛKTPOʹग़ྗ • allure
generate allure_results/* -o tmp/allure_report • ςετ݁ՌΛ)5.-ʹม • ϓϧϦΫΤετຖʹςετ݁Ռͷ)5.-Λ7FSDFMʹσϓϩΠ • ςετࣦഊ࣌ʹ7FSDFMͷ63-Λ#PU͕ίϝϯτͰڭ͑ͯ͘ΕΔ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ 117 Allure ReportΛಋೖ
Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ CI͕Failͨ͠ͱ͖ ϩάεΫγϣͷ֬ೝ͕໘
Bot͕ڭ͑ͯ͘ΕΔURLΛ֬ೝ✨ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘
Allure Report͓ΒͤBotΛ࡞ Flakyͳςετ͕ଟ͍💫 - CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ खܰ͞: ˒ˑˑˑˑ ޮՌ: ˒˒˒ˑˑ
ಓʹ͢ࡍʹେมͩͬͨ͜ͱ • CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ • CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ • FlakyΛθϩʹ͖͠Εͳ͍ Flakyͳςετ͕ଟ͍💫 121
CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ ϩάεΫϦʔϯγϣοτ ͚ͩͰ'BJMݪҼ͕Θ͔Βͳ͍🤯
capybara-playwright-driverΛಋೖ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌
• playwrightͱ͍͏ςετϑϨʔϜϫʔΫΛcapybara͔Β͑Δ • εΫϦʔϯγϣοτ͚ͩ͡Όͳ͘ςετ࣌ͷಈը͕ݟΒΕΔ • ։ൃऀπʔϧʹࡌͬͯΔΑ͏ͳωοτϫʔΫݟΒΕΔ • Allure Report ্ͰݟΒΕΔ
• Rails 7.1ʹऔΓࠐ·Ε͍ͯΔ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ 124 capybara-playwright-driverͱʁ
• playwrightͱ͍͏ςετϑϨʔϜϫʔΫΛcapybara͔Β͑Δ • εΫϦʔϯγϣοτ͚ͩ͡Όͳ͘ςετ࣌ͷಈը͕ݟΒΕΔ • ։ൃऀπʔϧʹࡌͬͯΔΑ͏ͳωοτϫʔΫݟΒΕΔ • Allure Report ্ͰݟΒΕΔ
• Rails 7.1ʹऔΓࠐ·Ε͍ͯΔ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ 125 capybara-playwright-driverͱʁ capybara.rb
• playwrightͱ͍͏ςετϑϨʔϜϫʔΫΛcapybara͔Β͑Δ • εΫϦʔϯγϣοτ͚ͩ͡Όͳ͘ςετ࣌ͷಈը͕ݟΒΕΔ • ։ൃऀπʔϧʹࡌͬͯΔΑ͏ͳωοτϫʔΫݟΒΕΔ • Allure Report ্ͰݟΒΕΔ
• Rails 7.1ʹऔΓࠐ·Ε͍ͯΔ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ 126 capybara-playwright-driverͱʁ
• playwrightͱ͍͏ςετϑϨʔϜϫʔΫΛcapybara͔Β͑Δ • εΫϦʔϯγϣοτ͚ͩ͡Όͳ͘ςετ࣌ͷಈը͕ݟΒΕΔ • ։ൃऀπʔϧʹࡌͬͯΔΑ͏ͳωοτϫʔΫݟΒΕΔ • Allure Report ্ͰݟΒΕΔ
• Rails 7.1ʹऔΓࠐ·Ε͍ͯΔ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ 127 capybara-playwright-driverͱʁ https://trace.playwright.dev/
• playwrightͱ͍͏ςετϑϨʔϜϫʔΫΛcapybara͔Β͑Δ • εΫϦʔϯγϣοτ͚ͩ͡Όͳ͘ςετ࣌ͷಈը͕ݟΒΕΔ • ։ൃऀπʔϧʹࡌͬͯΔΑ͏ͳωοτϫʔΫݟΒΕΔ • Allure Report ্ͰݟΒΕΔ
• Rails 7.1ʹऔΓࠐ·Ε͍ͯΔ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ 128 capybara-playwright-driverͱʁ
• playwrightͱ͍͏ςετϑϨʔϜϫʔΫΛcapybara͔Β͑Δ • εΫϦʔϯγϣοτ͚ͩ͡Όͳ͘ςετ࣌ͷಈը͕ݟΒΕΔ • ։ൃऀπʔϧʹࡌͬͯΔΑ͏ͳωοτϫʔΫݟΒΕΔ • Allure Report ্ͰݟΒΕΔ
• Rails 7.1ʹऔΓࠐ·Ε͍ͯΔ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ 129 capybara-playwright-driverͱʁ
CI্Ͱ͔͠ൃੜ͠ͳ͍Flakyͷ ݪҼ͕ෆ໌ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌
ಈըͱωοτϫʔΫτϨʔε Λݟͯղܾ✨ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌
capybara-playwright-driverΛಋೖ & Allure Reportͱඥ͚ Flakyͳςετ͕ଟ͍💫 - CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ खܰ͞: ˒˒ˑˑˑ ޮՌ:
˒˒˒ˑˑ
ಓʹ͢ࡍʹେมͩͬͨ͜ͱ • CIͰςετ͕Failͨ͠ͱ͖ɺϩάεΫγϣͷ֬ೝ͕໘ • CI্Ͱ͔͠ൃੜ͠ͳ͍FlakyͷݪҼ͕ෆ໌ • FlakyΛθϩʹ͖͠Εͳ͍ Flakyͳςετ͕ଟ͍💫 133
͘͝كʹམͪΔFlakyςετ… • Ӟͷ2݄ʹམͪΔςετ • ςετதʹΛލ͍Ͱ͠·ͬͨςετ • APIϨεϙϯε͕͍ͭΑΓͳ͔ͥͨΒͯ͘མͪͨςετ Flakyͳςετ͕ଟ͍💫 134
͘͝كʹམͪΔςετCI্ͰࣗಈͰRetryͤ͞Δ Flakyͳςετ͕ଟ͍💫 - FlakyΛθϩʹ͖͠Εͳ͍
͘͝كʹམͪΔςετCI্ͰࣗಈͰRetryͤ͞Δ Flakyͳςετ͕ଟ͍💫 - FlakyΛθϩʹ͖͠Εͳ͍ 'BJMͨ͠ςετ͚ͩ࠶࣮ߦ͢Δ
͘͝كʹམͪΔςετCI্ͰࣗಈͰRetryͤ͞Δ Flakyͳςετ͕ଟ͍💫 - FlakyΛθϩʹ͖͠Εͳ͍ ςετࣦഊͨ͠Βɺ࣍ͷStepͷςετͰ Capybaraͷͪ࣌ؒ͘ઃఆ͢Δ
͘͝كʹམͪΔFlakyͳςετ Flakyͳςετ͕ଟ͍💫 - FlakyΛθϩʹ͖͠Εͳ͍
ࣦഊͨ͠ςετΛ࠶ ࣗಈͰςετ͢ΔStepΛՃͯ͠ղܾ✨ Flakyͳςετ͕ଟ͍💫 - FlakyΛθϩʹ͖͠Εͳ͍
ࣦഊͨ͠ςετΛ࠶ ࣗಈͰςετ͢ΔStepΛՃ Flakyͳςετ͕ଟ͍💫 - FlakyΛθϩʹ͖͠Εͳ͍ खܰ͞: ˒˒˒˒ˑ ޮՌ: ˒˒˒˒˒
~·ͱΊ~ 2024ͷࣗಈςετͷঢ়گ🔍
ςετ DBTF $*ͷ࣌ؒ ฒྻ$PSF 'MBLZςετ ݸ
͘Β͍ͷ֬Ͱ$*͕མͪΔ (JU)VC"DUJPOTͷஈ ·ͱΊ 2023ͷςετͷঢ়گ🔍
2024ͷςετͷঢ়گ🔍 ςετ DBTF DBTF $*ͷ࣌ؒ
ฒྻ$PSF ඵ🎉 ฒྻ 'MBLZςετ ݸ ͘Β͍ͷ֬Ͱ$*͕མͪΔ ݸ🎉 ͘Β͍ͷ֬Ͱ$*͕མͪΔ (JU)VC"DUJPOTͷஈ 🎉 ·ͱΊ
ͬͨ͜ͱҰཡ • CapybaraͷػೳʹͤͯSleepΛআ • LoadingΛಈతʹͭHelper࡞ͬͯSleepΛআ • test-profͷbefore_allΛͬͯσʔλ࡞Λলུ • test-profͷlet_it_beΛͬͯσʔλ࡞Λলུ •
parallel_testsͷฒྻ࣮ߦΛ׆͔ͨ͢ΊʹϑΝΠϧׂ ·ͱΊ 144
ͬͨ͜ͱҰཡ • FactoryBot.create() Ͱͳ͘ FactoryBot.build_stubbed()Λ ͏ • ͚ͳ͍͍ͯ͘ςετɺ1ͭͷ it do
~ endʹ·ͱΊΔ • ͍Βͳ͍ػೳςετআ • LoadingΛͭॲཧՄೳͳΒআ • KnapsackPro gemར༻ ·ͱΊ 145
ͬͨ͜ͱҰཡ • ͍ςετϑΝΠϧ,͍ςετ, աڈࣦഊͨ͠ςετΛμο γϡϘʔυԽ • Next.jsͷBuildΛΩϟογϡԽ • capybara-playwright-driverՃ •
AllureReportՃ • GitHubͷAllureReportͷϦϯΫBot ·ͱΊ 146
͓ർΕ༷Ͱͨ͠🍻