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
25
18k
約9000個の自動テストの 時間を50分->10分に短縮 Flakyテストを1%以下に抑えた話
hatsu
October 25, 2024
Tweet
Share
More Decks by hatsu
See All by hatsu
Prism.parseで 300本以上あるエンドポイントに 接続できる権限の一覧表を作ってみた
hatsu38
1
140
MySQL初心者が311個のカラムにNot NULL制約を追加していってALTER TABLEについて学んだ話
hatsu38
2
290
introduction_scriptor_gem.pdf
hatsu38
1
150
Just a Rails Patch Update
hatsu38
2
820
Dive into MaintenanceTasks
hatsu38
1
160
GitHub Actions is Fun
hatsu38
1
170
Other Decks in Programming
See All in Programming
他言語経験者が Golangci-lint を最初のコーディングメンターにした話 / How Golangci-lint Became My First Coding Mentor: A Story from a Polyglot Programmer
uma31
0
180
いま中途半端なSwift 6対応をするより、Default ActorやApproachable Concurrencyを有効にしてからでいいんじゃない?
yimajo
2
430
バッチ処理を「状態の記録」から「事実の記録」へ
panda728
PRO
0
160
Leading Effective Engineering Teams in the AI Era
addyosmani
6
450
あなたとKaigi on Rails / Kaigi on Rails + You
shimoju
0
160
NixOS + Kubernetesで構築する自宅サーバーのすべて
ichi_h3
0
950
はじめてのDSPy - 言語モデルを『プロンプト』ではなく『プログラミング』するための仕組み
masahiro_nishimi
2
520
スマホから Youtube Shortsを見られないようにする
lemolatoon
27
32k
「ちょっと古いから」って避けてた技術書、今だからこそ読もう
mottyzzz
11
6.8k
PHPに関数型の魂を宿す〜PHP 8.5 で実現する堅牢なコードとは〜 #phpcon_hiroshima / phpcon-hiroshima-2025
shogogg
1
240
TFLintカスタムプラグインで始める Terraformコード品質管理
bells17
2
190
技術的負債の正体を知って向き合う / Facing Technical Debt
irof
0
180
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
30
2.9k
GitHub's CSS Performance
jonrohan
1032
470k
Embracing the Ebb and Flow
colly
88
4.9k
The Cult of Friendly URLs
andyhume
79
6.6k
How to Think Like a Performance Engineer
csswizardry
27
2k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Gamification - CAS2011
davidbonilla
81
5.5k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
620
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
A better future with KSS
kneath
239
18k
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
͓ർΕ༷Ͱͨ͠🍻