128
130

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RSpecのベストプラクティス集(Better Specs)の日本語まとめ

Last updated at Posted at 2014-05-01

[5/1追記]日本語版あったようですorz Better Specs

Better Specsから項目と簡単な説明をピックアップしています。

何点か似てるのあったのでマージしてます。

テストコードの書き方

describeでは対象メソッド名を明確にして、文章も短くしよっ

describeは長々文章で書くと読みにくいよ
メソッド名で簡潔に表現してね

# .はクラスメソッド、#はインスタンスメソッド
 describe '.authenticate' do 
 describe '#admin?' do 

contextを積極活用して、whenやwithで始まるような文章にしてね

context+when/withで読みやすさが全然ちがうね

context 'when logged in' do
  it { should respond_with 200 }
end

各テストでは1アサーションのみ実施しないとね

1つになんでもかんでも詰め込んじゃうとどこで失敗したかわかんないよー><

it { should respond_with_content_type(:json) }
it { should assign_to(:resource) }

可能性のあるケースはすべてテストしなきゃね

いい大人なんですから、成功ケース、境界値ケース、無効ケースなどはちゃんとテストしてね

describe '#destroy' do
  context 'when resource is found' do
    it 'responds with 200'
    it 'shows the resource'
  end
  context 'when resource is not found' do
    it 'responds with 404'
  end
  context 'when resource is not owned' do
    it 'responds with 404'
  end
end

基本はShouldよりもExpectを使った方がいいよ

古臭いshouldなんかやめて新しいexpectを使おうよ
ただ、subjectなどを使ってる場合はshouldを使ってもいいよ
でもね、全体的にshouldはなくしていく傾向にあるよ

関係するテストがいくつかあるならSubjectを活用しよう

同じものを複数のテストで使う場合はsubject{}を使った方がいいんだよ
あれ、subjectを使う・・・shouldを使う・・・expectは・・あれれ??

変数を使うならbeforeよりもletやlet!を使ったほうがいいよ

読みやすくなるし、何より遅延ロード(let)と即ロード(let!)を使い分けられるしね。
詳細はstack overflowのこの回答参照してね

Mock(ダミーケース)は過度に使わないようにしてね

極力実際のケースでテストするのがオススメですっ

context "when not found" do
  before { Resource.stub(:where).with(created_from: params[:id]).and_return(false) }
  it { should respond_with 404 }
end

テストに必要なデータだけロードしようね

必要以上にたくさんのデータをロードしちゃうと時間や負荷がかかっちゃいます
たくさんのレコードが必要と思うかもだけどそれは間違いだよっ

describe "User"
  describe ".top" do
    before { FactoryGirl.create_list(:user, 3) }
    it { expect(User.top(2)).to have(2).item }
  end
end

fixturesじゃなくてfactoriesを使おうね

fixturesは管理が大変だからfactories(FactoriGirl)使うのがいいよ

# BAD
user = User.create(
  name: 'Genoveffa',
  surname: 'Piccolina',
  city: 'Billyville',
  birth: '17 Agoust 1982',
  active: true
)
# GOOD
user = FactoryGirl.create :user

マッチャーは極力標準のものをつかいましょ

ここでいいマッチャーがないか2重確認してね

テストが膨れて重複してきたら共通化しようね

テストを書いていくうちにコード重複おこっちゃうけど、テストもDRYだよねっ

コントローラのテストはいらないよ、そのかわりインテグレーションテストしようね

モデルのテストしたらつぎはcapybaraなんかを使ってインテグレーションすればいいよ。
コントローラのテストって複雑だし無意味っぽいからさっ

テスト実行の仕方

guardをつかって自動テストしちゃおうよ

毎回テストを手動でやるのは飽きちゃうよね。だったらさguardで自動化しよっ。
そうすれば更新されたものに関する差分テストもできちゃうし一石二鳥だよ

プリロードしてテストを高速化しちゃおっかな

ZeusやZpinやSportなんかを使えばライブラリをプリロードしてくれて
コントローラ、モデル、ビュー、ファクトリ・・・なんかをリロードしてくれるよ

どれでもいいんだけど、Zeusは制約ちょっときついので気をつけてね。
(ruby2.0以上推奨でOSがFSEventかinotifyサポートしてないといけないよ)

もっと知りたいならここみてね

外部サービスを使うならHTTPリクエストはスタブ化しようね

外部サービスに依存したテストなんてもっての外だよ。
落ちたらテストできないし負荷もかけちゃうしね。
webmockのようなものを用いてスタブ化すべきだよ

ここらへん参考になるよ

フォーマッターで進捗のフォーマットを変更しちゃおっと

fuubarっていうgemを使えばテストの進捗を見やすくしてくれるよ

128
130
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
128
130

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?