RailsテストフレームワークRSpecのインストールと基本的な使い方、基礎文法:開発現場でちゃんと使えるRails 4入門(9)(3/3 ページ)
エンタープライズ領域での採用も増えてきたRuby on Railsを使ってWebアプリケーションを作るための入門連載。最新版の4に対応しています。今回は、Railsで振る舞い駆動開発を行うためのツールとしてRSpecを取り上げ、環境構築方法や、スペック、サンプル(example)、フック、エクスペクテーション、マッチャーなどの基本的な書き方を解説します。
保留とスキップ――「pending」「skip」メソッド
「it」メソッドにブロックを渡さず保留にすることもできますが、ブロックを実装しかかったサンプルを「保留」にしたいときは「pending」メソッドまたは「skip」メソッドを使います。
「pending」メソッドは、その実装しかかった振る舞いをチェックしエラーが発生すると「保留のサンプル」として扱われます。しかし、もしチェックをパスすると、それは「失敗」として扱われます。
一方の「skip」はそういった「しかかり」のチェックなしで「保留」とすることができます。RSpec 3より前は「pending」が「skip」として動作していました。
it "will be deleted when user deleted" do skip # or pending end #=> Pending: Borrowing will be deleted when user deleted # Not yet implemented # ./spec/models/borrowing_spec.rb:18
サンプルグループにおいて各サンプルの共通の処理をまとめておく「フック」
あるサンプルグループにおいて各「サンプル(example)」の共通の処理をまとめておく「フック」と呼ばれる仕組みがRSpecには用意されています。フックにはサンプルの前に実行する「before」フック、後に実行する「after」フック、ブロックを定義してその中でサンプルを実行する「around」フックがあります。
よく使う「before」フックの例を示します。
describe '#overdue?' do context 'due_back is tomorrow' do before do @borrowing = Borrowing.new(due_back: 1.days.since) end it "returns false when attribute is default(today)" do expect(@borrowing.overdue?).to be(false) end it "returns true when attribute is 2 days later" do expect(@borrowing.overdue?(2.days.since)).to be(true) end end end
また各フックのメソッドは、サンプルごとに1回行う場合は「:each」、サンプルグループの前に一回行う場合は「:all」の引数を取ることができます。デフォルトでは「:each」を取るようになっています。
「expect」メソッドで「エクスペクテーション」(起こるべきこと)を記述
アプリケーションの振る舞いを定義するとき、「サンプル(example)」の一つ一つには起こるべきことを記述します。これは「エクスペクテーション」と呼ばれ、一般に次の記法で書かれます。
expect(items).to include(item)
このエクスペクテーションはコンテナーオブジェクトの「items」に「item」が含まれていることを期待しています。
より細かく見ていくと、「expect」メソッドは振る舞いを期待するオブジェクトを引数に取ります。そしてメソッドチェーンしている「to」メソッドは「マッチャー」と呼ばれるRSpecのメソッドを引数に取ります。
期待するオブジェクトと振る舞いが適合するかを調べる「マッチャー」メソッド
このマッチャーとは、期待するオブジェクトと振る舞いが適合するかを調べるメソッドです。多様なマッチャーが用意されており、例として以下にいくつか紹介します。
- be_truthyとbe_falsey
「be_truthy」マッチャーは、引数に取ったオブジェクトが真であれば(「nil」または「false」でなければ)パスします。「be_falsey」マッチャーはその逆で「nil」または「false」であればパスします。
expect(borrowing.user) be_truthy
この例では「borrowing.user」が存在すればパスします。
RSpec 3より前のバージョンでは、それぞれ「be_true」「be_false」という名前でしたが、「true」や「false」と同一でなくてもパスできるため変更されました。同一かどうかを調べたいときは「be」マッチャーに「true」または「false」を渡します。
- 演算子のマッチャー
Rubyの演算子のマッチャーを以下に示します。
# books == [book] expect(books).to eq([book]) # books.size > 0 expect(books.size).to be > 0 # book.title =~ /Ruby/ expect(book.title).to match(/Ruby/)
ブロックのエクスペクテーション
「expect」はブロックを引数に取ることもできます。以下に例を示します。
expect { Book.create(name: 'test') }.to change{Book.count}.from(0).to(1)
このエクスペクテーションでは、「expect」のブロックを実行したとき、「change」マッチャーの方のブロックの値が「from」の引数から「to」の引数に変わることを期待しています。
RSpecの参考サイト
RSpecの体系は巨大で、紹介しきれなかった仕組みがたくさんあります。以下に参考になるリンクについて紹介しておきます。
RSpecの公式ドキュメントです。
RSpecの良い書き方について日本語を含む多言語で紹介しています。
また受け入れテストのフレームワーク「Turnip」もRSpecベースで実装されています。ぜひ自身でも調べてみてください。
次回は、ActionMailerを使ったメール機能
今回は、RSpecを例にRailsのテストについて解説しましたが、いかがでしたでしょうか。次回は、ActionMailerを使ったメール機能とActiveModelを使った永続化しないデータについて解説する予定ですので、お楽しみに。
- Railsアプリの設計をMVCごとに見直しリファクタリングして連載総まとめ
- 「設定より規約」のRailsで必要なセッティングの基礎知識と国際化/多言語対応
- ActionMailerのSMTP設定、テンプレートで送信&ActiveModelの基本的な使い方とバリデーション
- RailsテストフレームワークRSpecのインストールと基本的な使い方、基礎文法
- RailsのテンプレートエンジンSlimの書き方とActionViewのヘルパーメソッド、レイアウトの使い方
- Rails開発を面白くするアクションコントローラーの5大機能とルーティングの基本
- ActiveRecordにおけるモデルの「関連」とコールバックの使い方
- ActiveRecordの基本機能とマイグレーション、バリデーション
- 現場で使えるか見極めたいRails 4.1の新機能8選
- 特定データに関するscaffoldアクションの実装&基礎的なリファクタリング手法
- scaffoldの中身を理解するためにMVCコンポーネントと7つのアクションを個別で自作する
- 簡単インストールから始める初心者のためのRuby on Railsチュートリアル
著者プロフィール
林 慶(Rails技術者認定シルバー試験問題作成者)
平成2年大阪生まれ。2006年から高専で情報工学を学んでいたが当時は所謂プログラミングができない工学生だった。卒業後、高専の専攻科に上がったもののマンネリ化したキャンパスライフに飽きたため休学して渡豪。そこでプログラミングに対するコンプレックスを克服するためにRuby on Railsなどでアプリケーションを作ることを覚える。
帰国後から現在までは復学し推薦システムに関する研究を行いながら、アジャイルウェアでRuby on Railsアプリケーションの開発業務に従事している。
好きなメソッドはinject。
監修者プロフィール
山根 剛司(Ruby業務開発歴7年)
兵庫県生まれ。1997年からベンチャー系のパッケージベンダーで10年間勤務。当時、使用していた言語はJavaとサーバーサイドJavaScript。
2007年よりITコンサル会社に転職し、Rubyと出会って衝撃を受ける。基幹システムをRuby on Railsで置き換えるプロジェクトに従事。それ以来Ruby一筋で、Ruby on Railsのプラグインやgemも開発。
2013年より、株式会社アジャイルウェアに所属。アジャイルな手法で、Ruby on Railsを使って企業向けシステムを構築する業務に従事。
Ruby関西所属。好きなメソッドはtap。
Twitter:@spring_kuma、Facebook:山根 剛司
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Railsで目指せ、情熱エンジニア(9):Railsのコントローラをテストする
前回はインテグレーションテストとしてCucumberでテストを作成しました。今回はユニットテストとして、RSpecを使ってコントローラのテストを作成します - Railsで目指せ、情熱エンジニア(7):Railsの人気テストフレームワーク6選!
前回は具体的なWebアプリを例にして簡単なコードレビューをしました。今回からは、テストを使ったリファクタリングについて解説していきます - Railsコードリーディング〜scaffoldのその先へ〜(2):RSpecを使ったテストコードを読もう
コーディングとテストは切り離せない。RSpecを使ったテストコードの読み方の基本をマスターしよう - フレームワークで実践! JavaScriptテスト入門(5):Capybara-Webkit+Cucumber+Sinon.JSでJavaScriptのテストはここまで変わる
しっかりとJavaScriptをテストするために、今注目のJavaScript用のテストフレームワークをいくつか紹介し、その概要から実践的な使い方まで解説する連載。今回は、RubyでWebKitをヘッドレス化するフレームワーク、受け入れテストの記述が日本語でできるツール、スタブやモック、スパイが使えるライブラリを組み合わせたテスト方法などを紹介。 - iOSアプリ開発でもCI/継続的デリバリしようぜ(2):Kiwi+CocoaPodsで始めるiOSアプリの振る舞いテスト入門
現代の開発現場において欠かせないCI/継続的デリバリを、iOSアプリ開発に適用するためのツールやノウハウを解説する連載。今回は、iOSアプリの機能の振る舞いをテストするテスティングフレームワークの特長とインストールの仕方、主な使い方を解説します。 - 資格試験は転職に役立つか:Rails技術認定試験がスタート、合格者に聞いた
- @IT自分戦略研究所 資格辞典:Rails技術者認定試験(Rails 3 Certified Programmer)