Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
14k
約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
500
Dive into MaintenanceTasks
hatsu38
1
94
GitHub Actions is Fun
hatsu38
1
110
Other Decks in Programming
See All in Programming
The Efficiency Paradox and How to Save Yourself and the World
hollycummins
1
100
Thoughts and experiences on Rust and TypeScript
unvalley
2
200
Develop iOS apps with Neovim / vimconf_2024
uhooi
1
220
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
3
840
DevFest Tokyo 2025 - Flutter のアプリアーキテクチャ現在地点
wasabeef
2
220
似たもの同士のPerlとPHP
uzulla
1
110
5分ぐらいで分かる、トリミング機能の作り方
tsutsuitakumi
0
180
Cognitoが大型アップデート!Managed Loginとパスワードレスログインを実際に使ってみた@しむそくRadio Special Day1
tmhirai
2
160
cmp.Or に感動した
otakakot
3
330
Discord Bot with AI -for English learners-
xin9le
0
110
Reckoner における Datadog Browser Test の活用事例 / Datadog Browser Test at Reckoner
nomadblacky
0
180
新卒研修で作ったアプリのご紹介
mkryo
0
230
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
17k
A Tale of Four Properties
chriscoyier
156
23k
GraphQLとの向き合い方2022年版
quramy
44
13k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
150
What's in a price? How to price your products and services
michaelherold
243
12k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
The Language of Interfaces
destraynor
154
24k
GitHub's CSS Performance
jonrohan
1030
460k
Designing for Performance
lara
604
68k
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
Building Applications with DynamoDB
mza
90
6.1k
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
͓ർΕ༷Ͱͨ͠🍻