RSpec Performance Turning

4,689 views

Published on

社内のRSpec勉強会で使った資料です
http://sue445.hatenablog.com/entry/2013/07/30/235502

Published in: Technology

RSpec Performance Turning

  1. 1. Copyright Drecom Co., Ltd. All Rights Reserved. RSpec Performance Turning @sue445
  2. 2. Copyright Drecom Co., Ltd. All Rights Reserved. 自己紹介 sue445 ● @drecom ● 社内ツール系 ● 最近炎上PJに投入された ● コミュニティ ○ TDD BootCamp ○ 目黒.rb, 渋谷.rb, 新宿.rb ○ appengine ja night ● 【自称】サザエヴァンジェリスト ● 【他称】歩くJenkins、テストマニア ● 好きな言語はJava
  3. 3. Copyright Drecom Co., Ltd. All Rights Reserved. 去年の7月 https://twitter.com/sue445/statuses/226247880187449345
  4. 4. Copyright Drecom Co., Ltd. All Rights Reserved. 1年経ったので数えた ● Rails app x 7, gem x 4 ● Total Line: 12654 ● Line of Code: 5187 ● Total Coverrage: 平均95.34% ● Code Coverrage: 平均89.09% ● テスト:計1355個/人 http://sue445.hatenablog. com/entry/2013/07/01/154915
  5. 5. Copyright Drecom Co., Ltd. All Rights Reserved. 【宣伝】8/3(土) プリキュアハッカソン http://connpass.com/event/2772/
  6. 6. Copyright Drecom Co., Ltd. All Rights Reserved. Agenda 1. なぜパフォーマンスチューニングが必要 か 2. スローテストを見つける 3. スローテストをつぶす
  7. 7. Copyright Drecom Co., Ltd. All Rights Reserved. なぜテストコードにもパフォーマンスチューニン グが必要か? ● テストコードもプロダクトコードと同様に 資産なので、メンテナンスすべき ○ 1回しか動かないテストコードは書くだけ無駄 ● テストが遅いとTDDのサイクルが乱れ る ○ Red -> Green -> Refactoring ○ テストが遅いとストレスがマッハで死ぬ
  8. 8. Copyright Drecom Co., Ltd. All Rights Reserved. テストコードは高速に実行できるべき 遅いテストコードは結局実行されません。 状況が逼迫していれば実行に時間がかか るテストはテストスイートから削除されてし まいます。高速なテストコードを書いてくだ さい (from. クリーンコード)
  9. 9. Copyright Drecom Co., Ltd. All Rights Reserved. 【番外】テストコードのリファクタリング ● テストコードをリファクタリングして説明 的にすることで分かりやすくなる ○ setupと実行部を分けるだけでもだいぶ違う ● プロダクトコードと同様に資産なので(ry ● 「テストコード リファクタリング」でggrks
  10. 10. Copyright Drecom Co., Ltd. All Rights Reserved. もしリファクタリングしな かったら
  11. 11. Copyright Drecom Co., Ltd. All Rights Reserved. rm -rf spec/
  12. 12. Copyright Drecom Co., Ltd. All Rights Reserved. 理由 ● 某PJにアサインされた時にテストがメンテされ て無くて全然動かない ○ 最終更新が半年前・・・ ● 既存のテストを残したままでリファクタリングしよ うと思ったけど断念 ○ いろいろ初期化が重すぎてrspec起動だけで 2〜3分かかる(spring使っても数10秒くらい) ○ ストレスがマッハで1時間で断念 ● 1から全部書きなおした方が早いと判断 ○ 一応MergeRequestは通りましたw
  13. 13. Copyright Drecom Co., Ltd. All Rights Reserved.
  14. 14. Copyright Drecom Co., Ltd. All Rights Reserved. 2. スローテストを見つける ● rspec --profileでスローテストのワース ト10を抽出 ○ rspec 2.13.0以降なら --profile 5み たいに件数指定できる
  15. 15. Copyright Drecom Co., Ltd. All Rights Reserved. 通常のテスト結果の下に出る
  16. 16. Copyright Drecom Co., Ltd. All Rights Reserved. コンソール -> CSV -> Jenkinsでプロット Jenkinsにスローテストのグラフを表示する http://sue445.hatenablog.com/entry/2013/03/17/015836 Total worst 5
  17. 17. Copyright Drecom Co., Ltd. All Rights Reserved. 3. スローテストをつぶす
  18. 18. Copyright Drecom Co., Ltd. All Rights Reserved. Case1. テストの構造を見直す ● 1テストケースで1つだけテストする ○ プロダクトコードだけでなくテストコードもSRP を心がける ■ SRP = Single Responsibility Principle = 単一責任の原則 ○ 1つのitの中で複数のテストを実行しない ○ トータルの時間は変わらないけどit単体での 実行時間は短縮される ■ it単位でテストを実行する方法は後述
  19. 19. Copyright Drecom Co., Ltd. All Rights Reserved. Case2. 外部API系 ● Twitter APIとかFacebook APIとか ● webmockやmemoistで呼び出し回数を なくす or 減らす
  20. 20. Copyright Drecom Co., Ltd. All Rights Reserved. webmock URLとパラメータに対するレスポンスを自由に設定 できる
  21. 21. Copyright Drecom Co., Ltd. All Rights Reserved. memoist 同一引数に対するメソッドの戻り値を キャッシュする
  22. 22. Copyright Drecom Co., Ltd. All Rights Reserved. Case 3. DB系 ● 毎回必要最低限のデータだけを用意す る ○ データが多いとそれだけノイズになりメンテし づらくなる ○ config.fixture_path = "#{Rails.root} /db/seeds" とか○ねばいいと思うよ
  23. 23. Copyright Drecom Co., Ltd. All Rights Reserved. Case 3. DB系 DBを呼ぶ部分をmockに置き換えた方が いい? ● mockの多用は実装依存のコードになるりリファクタ リング時にテストがすぐに落ちるためため個人的に はおすすめしない ○ 前提条件をつくるためのデータのセットアップが 大変な場合にstub使うのはアリ(Controllerとか) ● なるべく本番に近い形でやった方がいいのでよっ ぽど遅い場合以外は普通にDB叩いていいと思う ● testは通るのにdevelopmentやproductionで落ち るのが一番面倒
  24. 24. Copyright Drecom Co., Ltd. All Rights Reserved. Case 4. category test ● 時間のかかるテストは予めマーキング しておく ○ 普段はそこだけテストを除外しつつ、Jenkins とかではテストさせる ● --tag ○ https://www.relishapp.com/rspec/rspec- core/v/2-4/docs/command-line/tag-option
  25. 25. Copyright Drecom Co., Ltd. All Rights Reserved. 4. more than faster !
  26. 26. Copyright Drecom Co., Ltd. All Rights Reserved. rspec --line-number ● 任意の行に対してテストを走らせる ○ 行によって it, describe, context 単位で実行で きる ○ JavaでいうところのQuick JUnit的なもの ○ ただしQuick Junitに比べたら若干違和感ある ● 手動で行番号設定するのは面倒なのでだいた いエディタと連携する ○ vim: RubyとvimでQuick JUnit風にテスト実行 ○ Emacs: できるよ!(by emacser) ○ RubyMine: 標準サポート
  27. 27. Copyright Drecom Co., Ltd. All Rights Reserved. preloader ● rubyを予め起動しておいてテストの実 行を早くする仕組 ● ruby 2.0で起動が早くなったのでいらな いんじゃないか説
  28. 28. Copyright Drecom Co., Ltd. All Rights Reserved. preloader比較 ● spork ○ railsじゃなくても使える ○ gem作る時はこれ一択? ● zeus ○ railsだけ ○ 使ったことないけど、よくゾンビになるという 噂を聞くw ● spring ○ railsだけ ○ 爆速なんだけどfactoryの更新を(デフォルト で?)リロードしてくれないのが難点
  29. 29. Copyright Drecom Co., Ltd. All Rights Reserved. guard ● ファイルに更新があったらテストを実行 するgem ● テストが通ったら全部テスト実行してく れる ● guard-shellと連携することで、RDocの 編集をほぼリアルタイムで確認できる ○ ファイル保存時にrdoc生成 ○ ブラウザのオートリロード
  30. 30. Copyright Drecom Co., Ltd. All Rights Reserved. guardであった悲しい話 ● Twitter APIを使ったとあるアプリで guardを入れた ● ファイル保存時にテスト実行 ● Twitter APIのRate Limitを一瞬でオー バー ● 規制解除されるまでテストが全部落ち る ● それ以来テストでguardは使ってないw
  31. 31. Copyright Drecom Co., Ltd. All Rights Reserved. 結論
  32. 32. Copyright Drecom Co., Ltd. All Rights Reserved. 結論 レベルを上げて物理で殴 ればいい(真理)
  33. 33. Copyright Drecom Co., Ltd. All Rights Reserved. 結論 ● 小手先のチューニングするよりもハイス ペックマシン使った方が楽 ● ハイスペックなJenkinsサーバ用意して そこでテストする ○ ほとんどの場合において人間のコスト >>>機械のコスト ○ fioに乗っければbundle installやDBのテスト も一瞬で終わりそうw ○ 時間を金で買う時代

×