エンタープライズ領域での採用も増えてきたRuby on Railsを使ってWebアプリケーションを作るための入門連載。最新版の4に対応しています。今回は、Railsで振る舞い駆動開発を行うためのツールとしてRSpecを取り上げ、環境構築方法や、スペック、サンプル(example)、フック、エクスペクテーション、マッチャーなどの基本的な書き方を解説します。
前回の「RailsのテンプレートエンジンSlimの書き方とActionViewのヘルパーメソッド、レイアウトの使い方」までで、Railsの基本的な使い方をMVCで分解して解説してきました。今回はRailsのテストについて解説します。
ある機能を作るにはいろいろな作り方がありますが、より短く分かりやすいコードに変えたとき、アプリケーションの「振る舞い」まで変わってしまうと問題ありですね。そうならないためにアプリケーションの振る舞いをあらかじめ定義しておきます。そしてコードを変えるたび定義通りに動いているかチェックすれば、バグや不具合を減らせそうです。
Railsには、そのためのツールがあり多くの開発現場でテスティングフレームワークとして使われています。まずはツールを使えるようにするところから紹介しましょう。
Railsには標準のテストフレームワークとして「MiniTest」があります。MiniTestはRubyの標準添付ライブラリでもあるので、すでになじみの方もいるかと思います。MiniTestはアプリケーションを作成した際、ルートディレクトリに「test」ディレクトリが作成されており、その中にテストを追加していきます。
一方で、Railsのテストフレームワークとしてデファクトスタンダードとなっているのが「RSpec」です。RSpecは「Behaviour-Driven Development(通称BDD、またはビヘイビア(振る舞い)駆動開発)」と呼ばれるソフトウェア開発アプローチのためのツールです。
「behaviour」とは「振る舞い」を意味し、BDDはプログラムを構成するオブジェクトやメソッドに期待する振る舞いを「サンプル(example)」として記述して開発を進めていきます。
いずれのテストフレームワークも長所と短所がありますが、ドキュメントや過去の資産が豊富なため開発現場ではRSpecを使うことが多いようです。本連載でも今回はRSpecについて解説します。
まずは、RSpecをRailsアプリケーションにインストールしましょう。
Gemfileに以下のコードを追加します。Gemfile中の「group」メソッドはブロックで定義するgemを、引数の環境にのみインストールします。
group :development, :test do gem 'rspec-rails', '~> 3.0.0' end
そして、次のコマンドでインストールと初期化を行います。必要に応じて「bundle exec」を付けて実行してください。
$ bundle install $ rails g rspec:install
これにより「development」と「test」環境にRSpecがインストールされました。
アプリケーションのルートディレクトリにコマンドの設定ファイルの「.rspec」と「spec」ディレクトリ、「spec」ディレクトリ以下に設定ファイルの「spec_helper.rb」と「rails_helper.rb」が生成されています。
また、最初からあったMiniTestの「test」ディレクトリは使うことがないので削除できます。
ここで以下に示す「.rspec」の大量の警告を出す「--warning」オプションをひとまず削除しておきます。「--color」オプションはRSpec実行時のログを色付けし、「--require」オプションはRSpec実行前に特定のファイルを読み込んでくれます。
--color --warning --require spec_helper
次に「test」環境のデータベースを下記のコマンドで構築します。
$ rake db:test:prepare
これでRSpecでテストを実行する準備は整いました。
本来であればプロジェクトの初期にここまでの準備をしておきます。なぜかと言うと、モデルやコントローラーを「rails generate」コマンドで生成した際に「spec」ディレクトリ以下に「models」や「controllers」のディレクトリと共にそれらの振る舞いを記述するファイルを生成してくれるからです。
試しに、次のコマンドで新しいモデルを作成してみましょう。
$ rails g model borrowing user:references book:references due_back:date invoke active_record create db/migrate/xxxxxxxxxxxxxx_create_borrowings.rb create app/models/borrowing.rb invoke rspec create spec/models/borrowing_spec.rb
マイグレーションファイルとモデルのソースと共に「spec/models/borrowing_spec.rb」という以下のファイルが生成されています。
require 'rails_helper' RSpec.describe Borrowing, :type => :model do pending "add some examples to (or delete) #{__FILE__}" end
これは「Borrowing」モデルの振る舞いを記述するファイルで、一般に「スペック(spec)」と呼ばれます。RSpecを実行すると、このスペックが処理され、アプリケーションの各要素が定義されている振る舞いに従うかチェックされます。
早速実行したいところですが、追加したマイグレーションを「test」環境のデータベースに反映する必要があります。おなじみの「rake db:migrate」コマンドに次のように環境を指定するオプションを付けて実行します。
$ rake db:migrate RAILS_ENV=test
それでは、次のコマンドでRSpecを実行してみましょう。特定のコンポーネント、ファイルだけ実行する場合は引数で指定します。
$ rspec $ rspec spec/models $ rspec spec/models/borrowing_spec.rb
現時点では、次のような実行結果が出力されていると思います。
* Pending: Borrowing add some examples to (or delete) /xxx/xxx/xxx/rails4_application_development_guide_sample/08/book_library/spec/models/borrowing_spec.rb # Not yet implemented # ./spec/models/borrowing_spec.rb:4 Finished in 0.00036 seconds (files took 1.64 seconds to load) 1 example, 0 failures, 1 pending
RSpecでは定義されている振る舞いの一つ一つを「サンプル(example)」と呼びます。RSpecの出力は、まずサンプルが成功であれば「.」、失敗であれば「F」、保留であれば「*」を出力します。その次に、各サンプルの詳細なレポート、最後に実行時間と全サンプル数、失敗したサンプル数、保留したサンプル数を出力します。
Copyright © ITmedia, Inc. All Rights Reserved.