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
RSpecの実行時間を1/5にした話
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ham
November 13, 2019
Programming
1.3k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RSpecの実行時間を1/5にした話
ham
November 13, 2019
More Decks by ham
See All by ham
プロダクト開発から業務改善コンサルまで。事業全体へ「染み出す」ことで広がるエンジニアの可能性
ham0215
0
170
AI時代に「チーム開発」を見直す ~個人アサインへのシフトと、AI駆動開発の実践例~
ham0215
0
63
機能開発を止めないために!運用と開発のバランスを可視化するために使っている指標をご紹介
ham0215
0
63
未来のAI駆動開発をイメージしながらAI開発基盤を整備する
ham0215
1
180
AIと過ごす1日〜全業務フローにAIを組み込む実践ガイド〜
ham0215
0
160
生成AIによる生産性向上〜テック企業やファインディの活用事例〜
ham0215
1
140
生成AI導入の効果を最大化する データ活用戦略
ham0215
0
640
データ駆動経営の道しるべ:プロダクト開発指標の戦略的活用法
ham0215
2
560
開発組織における意思決定の実例〜開発優先度・組織構成・ツール導入〜
ham0215
0
140
Other Decks in Programming
See All in Programming
Go 1.27からのGODEBUG / Go 1.27 リリースパーティ #go127party
mazrean
0
300
リアルな遅延を測る仕様
kota_yata
1
140
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
0
220
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
110
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
170
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
3
460
私のClaude Code活用法 (個人開発編) - PHPerKaigi mini #4(2026/08/24)
panda_program
1
210
バグを直したら useEffect が消えた
colorful12
3
840
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
53
35k
MIZARU@SPAJAM2026 第二回予選
1901drama
0
100
初めての模倣学習とVLA
natsutan
0
470
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
140
Featured
See All Featured
Designing Powerful Visuals for Engaging Learning
tmiket
1
530
Automating Front-end Workflow
addyosmani
1369
210k
Prompt Engineering for Job Search
mfonobong
0
440
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
RailsConf 2023
tenderlove
30
1.5k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
290
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
440
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
400
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
The browser strikes back
jonoalderson
0
1.6k
Transcript
RSpecの実行時間を1/5にした話 2019/11/13 Ebisu.rb #26 ham
自己紹介 name: naoto hamada twitter: @hamchance0215 biography: → → 最近はRoRのBackend
Engineer Javascriptの知識が古すぎるのでUpdate中
アプリ概要 概要 WebアプリケーションのAPI versions Ruby 2.4.1 Rails 5.2.3 Rspec-rails 3.9.0
エンドポイント数 79 ジョブ数 27
改善前 $ bundle exec rspec ……………*………………………………………… ……………*…………*……………………………… …………………………………………**…… Finished in
5 minutes 57 seconds 1366 examples, 0 failures, 5 pending
よくないところを直す
jobを同期処理にする 下記の記述が個別のテストケースごとに書いてあった。 Rails.application.config.active_job.queue_adapter = :test 個別に記載していると冗長だし漏れることもあるので、 config/environments/test.rbに移動 発生した問題 active storageにファイルを上げた時にファイルの解析が非同期で動いてお
り、それも同期処理になってしまいテストが遅くなった。 https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/blob/analyzable.rb#L37 →テストする必要ないのでmockにした。
外部接続のmockを整理 外部接続のmockがテストケースごとに書いてあった。 個別に記載していると冗長だし漏れることもあるので、 spec/spec_helper.rbに移動 config.before(:each) do allow(xxx).to receive(:yyy).and_return(true) ... end
Pending exampleを動かす(or 消す) pendingしているテストは意味がないので動くように直す。 本当に必要がないテストならば消す。 Pendingは極力使わない!!使ったらとしてもすぐ直す!!!!
database cleanerを外す
database cleanerを外す database cleanerを外した理由 • RSpecがテストごとにRollbackしてくれる • いろんなところに設定が増殖していた • ar_internal_metadataも消しちゃう
• truncateのスピードが遅い 詳細は下記にまとめています https://qiita.com/ham0215/items/7516117df87d2631e31d
profileで解析
遅いテストを探す rspecに--profileをつけると遅いテストをランキング形式で並べてくれます これで遅いテストを探しました $ bundle exec rspec --profile 10
create_list撲滅
create_list撲滅 FactoryBot.create_listは大量データを作る時に便利ですが1件ごとに insertを発行してしまいます FactoryBot.create_list(:user, 100) →100件insertが発行される users = FactoryBot.build_list(:user, 100)
User.import users →bulk insertで登録 詳細は下記にまとめています https://qiita.com/ham0215/items/dad6f5d3d63bd498d999
モデル生成のN+1対応
モデル生成のN+1対応 下記のように記述した時、review生成時にuserを毎回selectしてしまう。 let!(:user) { FactoryBot.create(:user) } # => insert user
let!(:draft_review) { FactoryBot.create(:review, :draft, user_id: user.id) } # => select user + insert review let!(:published_review) { FactoryBot.create(:review, :published, user_id: user.id) } # => select user + insert review 下記のようにモデルを直接渡せばselectされない let!(:draft_review) { FactoryBot.create(:review, :draft, user: user) } # => insert review 詳細は下記にまとめています https://qiita.com/ham0215/items/2943511a4336a77a6aed
sleepをスタブ化
sleepをスタブ化 外部接続のリトライなどで明示的にsleepしている処理があるが、テストでは sleepしなくて良い場合が多い →sleepをmockにする 発生した問題 spec/spec_helper.rbにsleepのmock定義したら、 RSpec::Mocks::OutsideOfExampleErrorが発生するようになった。 DBコネクションのsleepもmockになってしまったようだ https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L339 →テストケースごとに個別にmockを定義
改善後 $ bundle exec rspec ……………………………………………………… ……………………………………………………… ………………………………………………..… Finished in
1 minute 45.64 seconds 1366 examples, 0 failures 5 minute 58 seconds ↓ 約1/5に短縮!! 1 minute 45.64 seconds
まとめ テストコードはパフォーマンスを気にせず実装されていることが多く、ちょっと 改善するだけで効果絶大です!!(と個人的には思っています) 運用改善の時間が取れる場合はぜひ見直してみてはいかがでしょうか!?