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
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
610
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
260
距離関数を極める! / SESSIONS 2024
gam0022
0
280
最新TCAキャッチアップ
0si43
0
140
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
470
詳細解説! ArrayListの仕組みと実装
yujisoftware
0
580
聞き手から登壇者へ: RubyKaigi2024 LTでの初挑戦が 教えてくれた、可能性の星
mikik0
1
130
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
よくできたテンプレート言語として TypeScript + JSX を利用する試み / Using TypeScript + JSX outside of Web Frontend #TSKaigiKansai
izumin5210
6
1.7k
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
Featured
See All Featured
Being A Developer After 40
akosma
86
590k
Faster Mobile Websites
deanohume
305
30k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Designing for Performance
lara
604
68k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
The Invisible Side of Design
smashingmag
298
50k
Building Adaptive Systems
keathley
38
2.3k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
A Tale of Four Properties
chriscoyier
156
23k
GraphQLとの向き合い方2022年版
quramy
43
13k
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
͓ർΕ༷Ͱͨ͠🍻