edo1z blog

プログラミングなどに関するブログです

railsのテスト

controllerを自動作成する

$ rails generate controller StaticPages home help
      create  app/controllers/static_pages_controller.rb
       route  get 'static_pages/help'
       route  get 'static_pages/home'
      invoke  erb
      create    app/views/static_pages
      create    app/views/static_pages/home.html.erb
      create    app/views/static_pages/help.html.erb
      invoke  test_unit
      create    test/controllers/static_pages_controller_test.rb
      invoke  helper
      create    app/helpers/static_pages_helper.rb
      invoke    test_unit
      create      test/helpers/static_pages_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/static_pages.js.coffee
      invoke    scss
      create      app/assets/stylesheets/static_pages.css.scss

上記のファイルが作成される。テスト関連のファイルも作成してくれる。javascriptのファイルまで作成している。

test/controllers/static_pages_controller_test.rbが、static_pages_controllerのテストコード。中身は下記のようになっている。

require 'test_helper'

class StaticPagesControllerTest < ActionController::TestCase
  test "should get home" do
    get :home
    assert_response :success
  end

  test "should get help" do
    get :help
    assert_response :success
  end

end
言葉で表すと「Homeページのテスト。GETリクエストをhomeアクションに対して発行 (=送信) せよ。そうすれば、リクエストに対するレスポンスは[成功]になるはず。」となります。

(引用:http://railstutorial.jp/chapters/static_pages?version=4.2#cha-static_pages

Gemfileの修正

下記チュートリアルの内容。Production環境は、Herokuでpostgreを利用。テストのために、test環境の設定が必要。guardとかは、なくても基本的なことは動くらしい。

引用:http://railstutorial.jp/chapters/static_pages?version=4.2#sec-advanced_testing_setup

source 'https://rubygems.org'

gem 'rails',        '4.2.2'
gem 'sass-rails',   '5.0.2'
gem 'uglifier',     '2.5.3'
gem 'coffee-rails', '4.1.0'
gem 'jquery-rails', '4.0.3'
gem 'turbolinks',   '2.3.0'
gem 'jbuilder',     '2.2.3'
gem 'sdoc',         '0.4.0', group: :doc

group :development, :test do
  gem 'sqlite3',     '1.3.9'
  gem 'byebug',      '3.4.0'
  gem 'web-console', '2.0.0.beta3'
  gem 'spring',      '1.1.3'
end

group :test do
  gem 'minitest-reporters', '1.0.5'
  gem 'mini_backtrace',     '0.1.3'
  gem 'guard-minitest',     '2.3.1'
end

group :production do
  gem 'pg',             '0.17.1'
  gem 'rails_12factor', '0.0.2'
end

Gemfileを修正したら、bundle installする。production環境の設定は開発環境では不要なため、下記のようにする。

$ bundle install --without production

テストの実行

$ bundle exec rake test
テストスイートは期待どおりパス GREEN します (パスしたときにも色を表示できるようにするには、3.7.1のminitestレポーターをオプションで追加する必要があります)。ところで、テストの実行にはある程度時間がかかります。これには2つの要因が絡んでいます: (1) Spring serverを起動してRails環境を事前読み込みするのに時間がかかる。ただしこれは最初の1回だけです。(2) Rubyそのものの起動に時間がかかる (2番目の要因については、3.7.3で紹介するGuardを導入することで改善できます)。

引用:http://railstutorial.jp/chapters/static_pages?version=4.2#sec-advanced_testing_setup

テスト結果に色をつける

ターミナルでテストを実行しても、デフォルトだと文字に色がつきません。test/test_helper.rbの内容を下記のようにすると色がつきます。minitest-reporters gemが必要です。

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"
Minitest::Reporters.use!

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

テストの自動実行

Guardというのを使います。'guard-minitest'というgemです。gemのバージョンは、2.3.1です。

guardの初期化

guardを初期化するとGuardfileが作成されます。

$ bundle exec guard init

Guardfileの編集

初期のGuardfileは下記のようになってました。

# A sample Guardfile
# More info at https://github.com/guard/guard#readme

## Uncomment and set this to only include directories you want to watch
# directories %w(app lib config test spec features) \
#  .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}

## Note: if you are using the `directories` clause above and you are not
## watching the project directory ('.'), then you will want to move
## the Guardfile to a watched dir and symlink it back, e.g.
#
#  $ mkdir config
#  $ mv Guardfile config/
#  $ ln -s config/Guardfile .
#
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"

guard :minitest do
  # with Minitest::Unit
  watch(%r{^test/(.*)\/?test_(.*)\.rb$})
  watch(%r{^lib/(.*/)?([^/]+)\.rb$})     { |m| "test/#{m[1]}test_#{m[2]}.rb" }
  watch(%r{^test/test_helper\.rb$})      { 'test' }

  # with Minitest::Spec
  # watch(%r{^spec/(.*)_spec\.rb$})
  # watch(%r{^lib/(.+)\.rb$})         { |m| "spec/#{m[1]}_spec.rb" }
  # watch(%r{^spec/spec_helper\.rb$}) { 'spec' }

  # Rails 4
  # watch(%r{^app/(.+)\.rb$})                               { |m| "test/#{m[1]}_test.rb" }
  # watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
  # watch(%r{^app/controllers/(.+)_controller\.rb$})        { |m| "test/integration/#{m[1]}_test.rb" }
  # watch(%r{^app/views/(.+)_mailer/.+})                   { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
  # watch(%r{^lib/(.+)\.rb$})                               { |m| "test/lib/#{m[1]}_test.rb" }
  # watch(%r{^test/.+_test\.rb$})
  # watch(%r{^test/test_helper\.rb$}) { 'test' }

  # Rails < 4
  # watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
  # watch(%r{^app/helpers/(.*)\.rb$})     { |m| "test/helpers/#{m[1]}_test.rb" }
  # watch(%r{^app/models/(.*)\.rb$})      { |m| "test/unit/#{m[1]}_test.rb" }
end

使っているRailsのバージョンは、4.2.2なので、Rails 4の箇所のコメントを外してみます。変更があったら、該当のテストファイルのテストを実行するようです。

guardの実行

$ bundle exec guard

これで自動実行されるようになりました。