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