Everyday Rails RSpecによるRailsテスト入門でRSpec3に再入門![書評]


largeEveryday Rails - RSpecによるRailsテスト入門
が、RSpec3に対応したとの噂を聞いて1年ぶりに読み直しました。この書籍は著者や訳者さんが、しっかりとアップデートを続けてくれているので、最新の入門チュートリアル
としてRSpecの実践的な使い方が習得できるすばらしい本です。

今回は『Everyday Rails - RSpecによるRailsテスト入門
を読んでいく中で、特に印象に残った部分を中心にピックアップしていきます。ブログ駆動勉強ですw


🚌 Everyday Railsのサンプルソース

everydayrails/rspec_rails_4 - GitHub

この書籍ではできるだけRSpecやテストに集中できるようにサンプルソースが用意されています。しかもRails 4対応と至れり尽くせりです。すばらしい!
ターミナルで次のコマンドを実行すると、ローカルにソースコードをダウンロードできます。

git clone https://github.com/everydayrails/rspec_rails_4.git

😎 自分でコードを書く

勉強をするときにコピー&ペーストをするのではなく、自分でコードをタイピングしていくべき。
これは最近学習によって得られる知識がかなり変わることを実感しているのですごく共感できます!

🤔 テスト設計について

TDDで動くコードを書く前にRSpecのexample(itで始まる行)まで書いてテスト設計する。
いつもテストが先か、コードが先かで悩んでいました。この理由のひとつは動かない状態のテストの設計をどこに
書くかでしたが、この本を読んでいく中でこういうふうに先に設計すればTDDの流れの中で開発できるんだと感激ました^^

🗻 絶対に覚えておきたいRSpecを書くときの基本

* Specアウトラインをベースに考える
* example(itで始まる行)は原因究明しやすいように結果を1つに絞る
* 期待する結果は能動形、具体的に記述すること
* 「起きてほしいこと、起きてほしくないこと」の両方のテストを書くこと
* 境界値テストをすること
* スペックの可読性を高めることに努めること

😼 コントローラスペックについて

feature specに比べてコントローラスペックのほうが、少ないコストでテストできる。
コントローラのテストは、自動生成されていないコードで、テストにコストをかけて効果が高そうなものを選定するといい。
その結果たしっかりテストされたコントローラがあれば、アプリケーション全体のテスト網羅率を向上させることができる。

🐯 FactoryGirlのテクニック

次のようにファクトリを書くことで、home_phonework_phoneを使わけることができます。

FactoryGirl.define do
factory :phone do
association :contact
phone '123-555-1234'
factory :home_phone do
phone_type: 'home'
end
factory :work_phone do
phone_type: 'work'
end
end
end

また、『stympy/faker』を使うと、
住所やURL、メールアドレスなどのリアルなダミーデータを生成してくれます。

ただ日本語のふりがななどに対応しようと思うと『willnet/gimei
がオススメです。日本語のリアルな住所を組み合わせたダミーデータも簡単に作成することができます。

FactoryGirlはテストを遅くすることがあるそうですので、必要なときに適切に使うことが重要とのことです。

🐝 shared_examples

shared_exmamplesとは、いくつかのテストをグループ化して、メソッドのように何度も呼び出せる機能です。
下は公式サンプルのテストですが、これを見ると一目で分かると思います!

require "set"
RSpec.shared_examples "a collection" do
let(:collection) { described_class.new([7, 2, 4]) }
context "initialized with 3 items" do
it "says it has three items" do
expect(collection.size).to eq(3)
end
end
context "with an an item that is in the collection" do
it "returns true" do
expect(collection.include?(7)).to be_truthy
end
end
end
RSpec.describe Array do
# ↓shared_examplesを関数のように呼び出している
it_behaves_like "a collection"
end
#=> Array
#=> behaves like a collection
#=> initialized with 3 items
#=> says it has three items
#=> with an an item that is in the collection
#=> returns true
RSpec.describe Set do
# ↓shared_examplesを関数のように呼び出している
it_behaves_like "a collection"
end
#=> Set
#=> behaves like a collection
#=> initialized with 3 items
#=> says it has three items
#=> with an an item that is in the collection
#=> returns true

🐞 FactoryGirlでローカルのファイルを指定する方法

# ローカルのファイルを指定する方法
FactoryGirl.define do
factory :user do
avatar { File.new("#{Rails.root}/spec/factories/avatar.png") }
end
end

🎳 RSpecの便利マッチャー

# 正規表現でのチェック
expect("a string").not_to match /a regex/
# 配列のチェック
expect([1, 2, 3]).to match_array [2, 1, 3]

🗽 テストで特定の時間を指定する方法

travisjeffery/timecop - GitHub

特定の曜日や日にちに依存する処理がある場合に、そのテストをできる。また、時間をやめることができるのでタイムスタンプが正しく動いているかのテストなどができる。

😸 メールのテスト

bmabey/email-spec -GitHub

EmailについてテストをするためのGem。知らなかったけどこれはすごい使えそう。今度試してみます!

🚜 RSpec 3初心者向けの資料まとめ

RSpec 3初心者向けの資料まとめ[Ruby]

ちなみにそのほかのTDDやRSpecの入門記事も書いています。こちらも良ければぜひ読んでみてください^^

🏈 変更来歴

(2015-01-12 22:30) 既存記事から分離して新規作成

📚 おすすめの書籍

🖥 サーバについて

このブログでは「Cloud Garage」さんのDev Assist Program(開発者向けインスタンス無償提供制度)でお借りしたサーバで技術検証しています。 Dev Assist Programは、開発者や開発コミュニティ、スタートアップ企業の方が1GBメモリのインスタンス3台を1年間無料で借りれる心強い制度です!(有償でも1,480円/月と格安)