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
Talk about CI and testing of the STORES
Search
hogelog
November 08, 2023
Programming
2
520
Talk about CI and testing of the STORES
STORES Tech Talk - STORESのRailsを語る会の登壇「STORES ネットショップのCIとかテストについて話します」資料です。
hogelog
November 08, 2023
Tweet
Share
More Decks by hogelog
See All by hogelog
RubyのWebアプリケーションを50倍速くする方法 / How to Make a Ruby Web Application 50 Times Faster
hogelog
3
1.1k
なぜ Rack を理解すべきかプレトーク / Why should you understand Rack - Pre-talk
hogelog
0
320
ruby/irbへのコントリビュートと愉快な仲間たち / RubyKaigi 2024 Wrap Party
hogelog
0
160
RubyKaigi 2024 LT: Visualize the internal state of ruby processes in Real-Time
hogelog
0
190
小3の子がいるエンジニアの昔と今。
hogelog
0
1.4k
Kaigi_on_Rails_2022_Talk-hogelog.pdf
hogelog
6
1.4k
クックパッドインターンシップ 2018 API 編(前半)/ Cookpad internship 2018 Day 3: API
hogelog
0
9.6k
クックパッドの巨大 Rails アプリケーションの改善
hogelog
12
11k
自分相手にアプリケーションをつくり得られるもの
hogelog
0
990
Other Decks in Programming
See All in Programming
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
Conform を推す - Advocating for Conform
mizoguchicoji
3
690
How mixi2 Uses TiDB for SNS Scalability and Performance
kanmo
35
14k
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
170
CI改善もDatadogとともに
taumu
0
110
2024年のkintone API振り返りと2025年 / kintone API look back in 2024
tasshi
0
220
Open source software: how to live long and go far
gaelvaroquaux
0
630
ペアーズでの、Langfuseを中心とした評価ドリブンなリリースサイクルのご紹介
fukubaka0825
2
310
2024年のWebフロントエンドのふりかえりと2025年
sakito
1
240
ファインディの テックブログ爆誕までの軌跡
starfish719
2
1.1k
富山発の個人開発サービスで日本中の学校の業務を改善した話
krpk1900
4
380
Flutter × Firebase Genkit で加速する生成 AI アプリ開発
coborinai
0
150
Featured
See All Featured
The Language of Interfaces
destraynor
156
24k
A designer walks into a library…
pauljervisheath
205
24k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
4 Signs Your Business is Dying
shpigford
182
22k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
Side Projects
sachag
452
42k
Adopting Sorbet at Scale
ufuk
74
9.2k
Building Your Own Lightsaber
phodgson
104
6.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
29
2.2k
Transcript
STORES 株式会社 STORES ネットショップのCIとかテストに ついて話します 2023-11-08 @hogelog CTO室技術基盤グループマネージャ 小室 直
2023年11月
自己紹介 技術基盤グループ マネージャ @hogelog ウェブ企業でサービス開発エンジニア、基盤領域エンジニアやマ ネージャーを経由して、現在はまたエンジニアマネージャに。 サーバサイドとインフラの間や組織と組織の間に落ちているボー ルを拾うのが割と好きです。
CIとは 3 - CI = Continuous Integration(継続的インテグレーション) - CIでは色々なものを動かします -
テスト - Lint - ……
STORES ネットショップのテスト 4 - STORES ネットショップのRailsアプリケーションのテストに関し てあれこれ雑多に紹介します
STORES ネットショップのテスト行数推移 5 - 2023年11月現在: 22万6185行 - `find spec -type
file -name '*.rb' | xargs wc -l`
CI実行環境と実行時間 6 - CI実行環境: CircleCI - 10m+ もしばしば☔
ある程度以上規模のRailsアプリケーションテストの問題 7 - 問題 - 結果が不安定 - 時間がかかる - お金がかかる
- なんとかする - 不安定なテストの改善 - テストの高速化 ( )≒ 時間がかかる
不安定なテストの安定化
テスト安定化: タイミング問題で落ちるテストの修正 9 - 複数データが同一秒に作成されると落ちるテスト - 複数データが同一秒に作成されないと落ちるテスト - 他
テスト安定化: 不安定なテストの改善(レスポンスのブラウザキャッシュ) 10 - feature specでブラウザがレスポンスをキャッシュしてしまい実 行順によっては失敗する場合があった - 現在はテスト実行時は `expires_in`
を無効化している - 後日ブログで再現コードや他の解決方法について解説します module DisableBrowserCacheDuringTest def expires_in(seconds, options = {}) if seconds == 0 super end end end ActionController::ConditionalGet.prepend(DisableBrowserCacheDuringTest)
テスト安定化: 不安定なテストの改善(遅い回線のエミュレート) 11 - CIでネットワークが詰まった時に不安定になるテストを見つけるた めの遅い回線のエミュレート if ENV["CAPYBARA_EMULATE_SLOW_NETWORK"] emulate_network_config =
{ latency: 100, # 100ms download_throughput: 64 * 1024 / 8, # 64Kbps upload_throughput: 64 * 1024 / 8, # 64Kbps } elsif ENV["CAPYBARA_EMULATE_NETWORK_CONFIG"] emulate_network_config = JSON.parse(ENV["CAPYBARA_EMULATE_NETWORK_CONFIG"], symbolize_names: true) end if emulate_network_config Capybara.current_session.driver.browser.devtools.network.emulate_network_conditions(offline: false, **emulate_network_config) end
テスト安定化: 不安定なテストの改善(集計と継続的取り組み) 12 - 不安定なテストをスプレッドシートに集計、可視化し改善に日々取 り組み
テスト安定化: rspec --only-failures 13 - 実行に失敗したテストのみ再実行するフラグ - 不安定なテスト失敗時、テストを全て実行しなおす時間をスキップ できる
テスト安定化: rspec-retry 14 - 実行に失敗したテストのみ再実行するgem - 同一rspec実行プロセスの中で再実行されるので--only-failuresよ りも速いことが期待できる
テスト再実行系ソリューションの注意点 15 - 不安定なテストが気づかぬうちに増えていく - 不安定なテストが増えると実行時間も伸びる - 継続的な改善活動に取り組んでいない場合、必ず不安定なテストは 増えていきます -
CircleCIならばCircleCI Insightsなどを見るのもオススメ - そもそも再実行系ソリューションは可能な限り導入を避けたい
テストの高速化
テスト高速化: Capybara.default_max_wait_time の調整 17 - feature specの失敗時、Capybara.default_max_wait_time時間 待つ場合があるので、長すぎない程度の適切な時間を設定 - 現在の設定:
`default_max_wait_time = 10`
テスト高速化: 大量に作られるテストデータの削減 18 - 検証したい条件に関連しない無駄なテストデータ作成を削減 - かなり地道 - 101.times {
|i| Fabricate.create(...) } + Fabricate.create(...)
テスト高速化: テスト分割と並列実行(CircleCI) 19 - 現在の設定: `parallelism: 16` - 💰
テスト高速化: テスト分割と並列実行(parallel_rspec) 20 - CircleCIのparallelismはマシンリソースを使いきれないので parallel_rspecで並列度を更に向上📈 - 複雑度も向上📈、悩ましい
テスト高速化: テスト分割と並列実行(parallel_rspec不安定テストの再実行) 21 - rspec-retry + 失敗したspecの再実行 - rspec-retryでは救いきれないパターンを再実行でカバー -
parallel_rspec x rspec --only-failures がうまく動かないので自 前スクリプトで before_result = File.read("tmp/test_results/failing_specs.log") failed_output = (before_result =~ /Failed examples:[\r\n]+(.+)/m && $1) failing_examples = failed_output.lines.map do |line| $1 if line =~ %r[rspec ('.+'|./spec/.+:\d+)] end.compact puts "Rerun #{failing_examples.size} examples" command = "bundle exec rspec --no-fail-fast -- #{failing_examples.join(" ")}" puts command exec command
テスト(CI)高速化: CircleCI workspaceの省サイズ化 22 - ジョブ間のデータ共有に用いるworkspaceの省サイズ化`rm -rf .git/ ...`
テスト(CI)高速化: 細かい改善 23 - テスト失敗あるときのみ `rspec --only-failures` 実行 - 無駄なapt-get
installの削減 - 他
テスト(CI)高速化: 遅いテストを観測し改善する継続的な取り組み 24 - 基本は rspec --profile - 集計しavg, p95など可視化すると効果的
- CircleCI Insightsなども有用
テスト安定化・高速化 25 - しばらくテスト安定化・高速化の取り組みがない、アクティブに開 発されているRailsアプリケーションは必ずテストが不安定になり 遅くなっています - CIの結果や設定ファイルをじっと見ると改善できる場所が必ず浮か んでくる -
できるまでやればできる
今後のテストについて 26 - CircleCI -> GitHub Actions, CodeBuild, Jenkins, …?
- 不安定なテスト、遅いテストがまた蓄積しつつある - To be continued...