RSpec, Guard の設定 : 小林研 Rails Tips (47)

はじめに

Rails Tips の 47 回目です。昨日は Rails ガイドの 3.2 節で rails new をしたところでした。Rails ガイドではテストなどはスキップしているのですが、やはり通常はテストを先に記述するべきです。今回は Rails に標準で用意される test ではなく、RSpec というテストフレームワークを設定します。

Rails をはじめよう - Railsガイド

RSpec のインストール

最初に RSpec をインストールします。たまにしか実行しないとすぐに忘れてしまうので、 --help で確認しましょう。 rspec:install というジェネレータがありますね。検索するよりまずはヘルプを見るのが一番です。

$ bin/rails g --help
Usage:
  bin/rails generate GENERATOR [args] [options]

General options:
  -h, [--help]     # Print generator's options and usage
  -p, [--pretend]  # Run but do not make any changes
  -f, [--force]    # Overwrite files that already exist
  -s, [--skip]     # Skip files that already exist
  -q, [--quiet]    # Suppress status output

Please choose a generator below.

Rails:
  application_record
  benchmark
  channel
  controller
  generator
  helper
  integration_test
  jbuilder
  job
  mailbox
  mailer
  migration
  model
  resource
  scaffold
  scaffold_controller
  system_test
  task

ActiveRecord:
  active_record:application_record
  active_record:multi_db

Erb:
  erb:controller
  erb:mailer
  erb:scaffold

Haml:
  haml:application_layout

Rspec:
  rspec:channel
  rspec:controller
  rspec:feature
  rspec:generator
  rspec:helper
  rspec:install
  rspec:integration
  rspec:job
  rspec:mailbox
  rspec:mailer
  rspec:model
  rspec:request
  rspec:scaffold
  rspec:system
  rspec:view

Stimulus:
  stimulus

TestUnit:
  test_unit:channel
  test_unit:controller
  test_unit:generator
  test_unit:helper
  test_unit:install
  test_unit:integration
  test_unit:job
  test_unit:mailbox
  test_unit:mailer
  test_unit:model
  test_unit:plugin
  test_unit:scaffold
  test_unit:system

早速、インストールしてみます。 .rspec は設定ファイルです。spec フォルダの下には、spec_helperrails_helper が用意されます。前者は RSpec 自体のシステムのヘルパーであり、後者は Rails に関するヘルパーです。RSpec 自体は Rails 以外でも利用されるので、Rails に関係しないものは spec_helper の方に記述することになります。

$ bin/rails g rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

早速 .rspec に以下のように一行追加します。テストの結果を documentation 形式で表示します。デフォルトは progress で一つのテストごとに . を一つ表示するだけです。開発中は documentation にしておくことで、どんなテストが実行されているかの仕様を確認することができます。基本的には、後で設定する guard により関連するテストしか実行されないので、この状態でもそれほど気にはならないと思います。

--require spec_helper
--format documentation

spec/rails_helper.rb では取り急ぎ二つ修正します。一つは中断にある以下の行のコメントを外すことです。これによって後で設置する spec/support/shared_example.rb を自動的に読み込みます。

Rails.root.glob('spec/support/**/*.rb').sort.each { |f| require f }

また、最後の end の前に以下の行を追加します。テストデータである fixtures を全てのテストで自動的に読み込むようにする設定です。

config.global_fixtures = :all

先ほど読み込みの設定を行った spec/support の下に shared_example.rb を空で作成します。以前紹介した shared example は使うたびにここに追加していきます。

mkdir -p spec/support
touch spec/support/shared_example.rb

Guard のインストール

次に保存したファイルに関連したテストだけを実行してくれる Guard をインストールします。

$ bundle exec guard init
21:12:05 - INFO - Writing new Guardfile to /Users/hkob/Library/CloudStorage/Dropbox/rails/hkob_blog/Guardfile
21:12:05 - INFO - rspec guard added to Guardfile, feel free to edit it

guard-rspec でインストールしたため、デフォルトでだいたいいい感じの設定が Guardfile に設定されています。ただ、小林研の使い方に合わせて以下のような修正を行います。

  • controller spec は実施せず、代わりに request spec を実施する

            # rspec.spec.call("controllers/#{m[1]}_controller"),
            rspec.spec.call("requests/#{m[1]}"),
    
  • views を修正した時に、request spec も実行する

        # Capybara features specs
        # watch(rails.view_dirs)     { |m| rspec.spec.call("features/#{m[1]}") }
        watch(rails.view_dirs) do |m|
          [
            rspec.spec.call("requests/#{m[1]}"),
            rspec.spec.call("features/#{m[1]}"),
          ]
        end
    
  • fixutres を修正した時に model のテストを実行 (行を追加)

      watch(%r{^spec/fixtures/(.+)\.yml$}) { |m| "spec/models/#{m[1].singularize}_spec.rb" }
    

おわりに

ここまでのリポジトリを以下のリポジトリに置きました。このリポジトリの REAME.md にこれまでのブログ記事へのリンクをまとめておきましたので、こちらもご確認ください。

https://github.com/hkob/hkob_blog