46
45

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.

Railsでrspecを使うように設定する

Last updated at Posted at 2017-06-11

単純なメモのみです。

やりたいこと

なぜrspec?

組み込みのminitestではだめなの?

デフォルトでは、rails newした際には、テスト用のフレームワークとしてMinitestが最初から利用できるようになっています。
(参考: Rails テスティングガイド)

参考にさせていただいているRailsチュートリアルでも、現時点(第4版)でもテストはMinitestを使った形式で解説されています。

以前はrspecだったようですが、rspecは学習コストも高いとのことで標準のMinitestに切り変えたそうです。
(参考: Railsチュートリアルの歩き方(第4版))

個人的には、お世話になっているRedmineのテストがMinitestが中心なため、特にこれといった準備の要らないMinitestが好きだったりします。

きっかけは現場がそうだったから

ただ、現場でrspecしかいじっていなくてよく分からない / rspecを勉強しないといけない...といったケースが出てきましたので、だんだんとrspecを使うようになって来ました。

そんなこんなで、まずはrspecを使えるようにしてみます。

Gemfile調整とBundle install

まずはお約束のrails new などでアプリケーションの雛形を作ります。
その後での作業になります。

※ rails newする時に、「後でrspecにするから標準のテストは要らない!」という場合は、”-T” オプションを付けるとテスト作成をスキップしてくれます (20170613:追記)

Gemfileのdevelopment, testの箇所に rspec-rails を追加します。
(この例ではバージョンを固定していません)

rspecのgemが必要なのは、開発/テスト環境のみ。
本番にデプロイする際には必要なければ、group のブロックの中に入れておきます。

group :development, :test do
  gem 'rspec-rails'
  gem 'factory_girl_rails'
end

設定を追加したら、bundle install します。

  • この例では、通常はシステムのgemと混ざらないように--path指定でアプリケーションの直下にgemをinstallしています
  • Deploy先(production)は今のところ無いのとproductionではテスト関連のものは使わないので、--without production を指定
$ $ bundle install --without production --path=vendor/bundle

基本の設定

rspecもrailsのジェネレータを使って基本設定を作ります。
(rspec --initだと、rails_helper.rbができません)

$ bundle exec rails g rspec:install
Running via Spring preloader in process 49348
   identical  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
      
$ tree spec/
spec/
├── rails_helper.rb
└── spec_helper.rb

0 directories, 2 files      

からっぽでも試す

rspecコマンドで、spec/ 以下のテストが実行されます。
rspecの実行タスクは、標準でRake taskが用意されているので、そちらからの実施でも大丈夫です。

テストはまだ無いので、結果は空っぽです。

$ bundle exec rspec
No examples found.


Finished in 0.00066 seconds (files took 0.19928 seconds to load)
0 examples, 0 failures

# rake taskでの呼び出し(オプション指定できない)
$ bundle exec rake spec
No examples found.


Finished in 0.00104 seconds (files took 0.22282 seconds to load)
0 examples, 0 failures

(※ Rails5だと、rake specでもrails specでもどちらでも大丈夫です)

既存のモデルにspecを追加する

rspec-railsのジェネレータを使って、各specの雛形を作ります。

まずは既存のモデルのspecを追加してみます。

# チュートリアルで作ったモデル:Userのテスト追加
$ bundle exec rails generate rspec:model User
Running via Spring preloader in process 49957
      create  spec/models/user_spec.rb
      invoke  factory_girl
      create    spec/factories/users.rb


# 上記で作ったテストの実行
$ bundle exec rspec spec/models/
*

Pending: (Failures listed here are expected and do not affect your suite's status)

  1) User add some examples to (or delete) xxxxx/toy_app/spec/models/user_spec.rb
     # Not yet implemented
     # ./spec/models/user_spec.rb:4


Finished in 0.00145 seconds (files took 4.32 seconds to load)
1 example, 0 failures, 1 pending

オプションにあったscaffoldも試してみます。
ルーティングやコントローラのspecが追加されます。

$ bundle exec rails generate rspec:scaffold User
Running via Spring preloader in process 49784
      create  spec/controllers/users_controller_spec.rb
      create  spec/views/users/edit.html.erb_spec.rb
      create  spec/views/users/index.html.erb_spec.rb
      create  spec/views/users/new.html.erb_spec.rb
      create  spec/views/users/show.html.erb_spec.rb
      create  spec/routing/users_routing_spec.rb
      invoke  rspec
      create    spec/requests/users_spec.rb

ひとまずこんな感じで、rspecを使う準備ができました。

中身を見てみます

modelに対するspecは、"pending" でほとんど内容はありません。
railsのgeneratorで作ったモデルもまだメソッドが何もないので、そちらに合わせて自分で処理を書いていく感じになります。

controllerに関しては、railsのgeneratorでの作成段階で、CRUDの標準的なメソッドが一式追加されるので、それに合わせてspecも基本的なテスト項目が生成されています。(便利!)

  # users_controller_spec.rb の抜粋
  describe "GET #index" do
    it "assigns all users as @users" do
      user = User.create! valid_attributes
      get :index, params: {}, session: valid_session
      expect(assigns(:users)).to eq([user])
    end
  end

  describe "GET #show" do
    it "assigns the requested user as @user" do
      user = User.create! valid_attributes
      get :show, params: {id: user.to_param}, session: valid_session
      expect(assigns(:user)).to eq(user)
    end
  end

あとは頑張ってテストの内容を少しずつ増やしていく形になります。

まとめ

以上、またもや拙いメモですが、こんな流れとなりました。

  • Railsの基本はMinitestの環境が用意されている
  • どうしてもrspecに揃えないといけない場合は追加のgem, 設定が要る

参考にしているサイト

rspecはまだまだ勉強中ですが、マッチャー(期待している文字列が結果に含まれているかどうか)は良く参照しますので、なんだかんだでこちらを良く見ています。

また、おかげさまで、rspecに関する情報はとてもたくさんあることと、現場でのまわりの皆さんの書き方やオープンソースのアプリケーションの書き方を眺めながら、なんとか進めている感じです。

memo: Relishについて

rspec-coreのドキュメントは、http://rspec.info ではなくRelishというドキュメンテーション用のサイトで公開されています。

rspec-coreのソースコードのうち、Cucmberで書かれたfeatures/ ディレクトリ一式がそのままドキュメントに変換されて公開されているみたいです。
Relishへのサイトへのドキュメントの反映を実施するために、relishというgemがあります。rspec-coreのrake taskには、この操作を行うtaskも用意されています。

もちろん、 https://github.com/rspec/rspec-core を手元にcloneしてきて、featuresのテスト(cucumber) を走らせることもできます。

# 実行例
$ bundle exec cucumber features/command_line/dry_run.feature 
Using the default profile...
.....

1 scenario (1 passed)
5 steps (5 passed)
0m1.050s

Cucumberに関してはまだまだ追いついていないので、完全に脱線です...。

46
45
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
46
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?