Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
RSpecの実行時間を1/5にした話
ham
November 13, 2019
Programming
0
490
RSpecの実行時間を1/5にした話
ham
November 13, 2019
Tweet
Share
More Decks by ham
See All by ham
RDB脳からFirestore脳へ
ham0215
0
45
GraphQLの関連タイプを辿る脆弱性
ham0215
0
37
JWTを保存する場所について
ham0215
0
81
MySQLのUPDATE文にORDERが指定できると知った件
ham0215
0
38
非エンジニアのSQL入門
ham0215
0
18
Other Decks in Programming
See All in Programming
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
100
20220706_Google Apps Scriptを実演で学ぶ~ GAS × Slack ~
apachan
2
620
アジャイルで不確実性に向き合うための開発タスクの切り方
tanden
4
1.1k
話題の AlloyDB は本当に凄いデータベースなのでプレビューを使い倒した #devio2022
maroon1st
0
13k
Carp言語さわってみた 〜鯉を取り戻せ編〜
tsin45
0
110
パラメタライズドテスト
ledsun
0
220
パスワードに関する最近の動向
kenchan0130
1
330
Lookerとdbtの共存
ttccddtoki
0
640
Now in Android Overview
aosa4054
1
400
Amazon SageMakerでImagenを動かして猫画像生成してみた
hotoke_neko
0
110
SAM × Dockerでサーバーレス開発が超捗った話
yu_yukk_y
1
370
ESM移行は無理だけどおれもSindreのライブラリが使いたい!
sosukesuzuki
2
550
Featured
See All Featured
Building Applications with DynamoDB
mza
84
4.8k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
62k
Keith and Marios Guide to Fast Websites
keithpitt
404
21k
Embracing the Ebb and Flow
colly
73
3.4k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
107
16k
What's in a price? How to price your products and services
michaelherold
229
9.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
316
19k
WebSockets: Embracing the real-time Web
robhawkes
57
5.6k
Large-scale JavaScript Application Architecture
addyosmani
499
110k
YesSQL, Process and Tooling at Scale
rocio
157
12k
10 Git Anti Patterns You Should be Aware of
lemiorhan
638
52k
The World Runs on Bad Software
bkeepers
PRO
57
5.4k
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
まとめ テストコードはパフォーマンスを気にせず実装されていることが多く、ちょっと 改善するだけで効果絶大です!!(と個人的には思っています) 運用改善の時間が取れる場合はぜひ見直してみてはいかがでしょうか!?