【Rails】Railsにおけるユニットテストの前準備_Minitest-reporterとGuardの導入

Rails tutorialの第3章を終えました。
その時の気づいたこととか備忘録です。
今回はユニットテスト準備について

railstutorial.jp

ユニットテスト

ユニットテストを行う前に、テスト用の設定を行った方が気分がいいです。
ここではRailsでの成功/失敗の表示設定を行うminitest-reporter
ファイルの変更を検出して必要なテストだけを自動実行してくれるGuardについて

minitest-reporter

ユニットテストを行う際は、テスト結果が色でわかる方がわかりやすいです。
minitest-reporter
$rails tを行った時にターミナル上で成功した時に緑色、失敗した時には赤色。
といった色を表示することができます。

導入

まずGemfileに

group :test do
  gem 'minitest-reporters'
end

を追加します。

$ bundle installやら$bundle updateを行い、 テスト用ヘルパーファイルtest/test_helper.rbに下記を追記します

test/test_helper.rb

require "minitest/reporters"
Minitest::Reporters.use!

結果

これで、$rails tを行うことでテスト結果に色がつきます。
成功例

rails t 成功
rails t 成功

失敗例

rails t 失敗
rails t 失敗

Guard

よくあるユニットテストの自動化を行います。
Guard$rails tを使うときに、ターミナルから手動でコマンドを打ち、実行する点を自動化し、ファイルを変更した際に自動的にテストコードを実行することができます。

導入

Gemfileに下記を追加します。

  gem 'guard'
  gem 'guard-minitest'



$ bundle installやら$bundle updateを行ったあと

$ bundle exec guard init

を行うとGuardfileが自動生成されます。このGuardfileを編集します。

Guardfileの編集方法はRailsチュートリアルにあるファイルは流用がききます

# Guardのマッチング規則を定義
guard :minitest, spring: "bin/rails test", all_on_start: false do
  watch(%r{^test/(.*)/?(.*)_test\.rb$})
  watch('test/test_helper.rb') { 'test' }
  watch('config/routes.rb')    { integration_tests }
  watch(%r{^app/models/(.*?)\.rb$}) do |matches|
    "test/models/#{matches[1]}_test.rb"
  end
  watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches|
    resource_tests(matches[1])
  end
  watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches|
    ["test/controllers/#{matches[1]}_controller_test.rb"] +
    integration_tests(matches[1])
  end
  watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches|
    integration_tests(matches[1])
  end
  watch('app/views/layouts/application.html.erb') do
    'test/integration/site_layout_test.rb'
  end
  watch('app/helpers/sessions_helper.rb') do
    integration_tests << 'test/helpers/sessions_helper_test.rb'
  end
  watch('app/controllers/sessions_controller.rb') do
    ['test/controllers/sessions_controller_test.rb',
     'test/integration/users_login_test.rb']
  end
  watch('app/controllers/account_activations_controller.rb') do
    'test/integration/users_signup_test.rb'
  end
  watch(%r{app/views/users/*}) do
    resource_tests('users') +
    ['test/integration/microposts_interface_test.rb']
  end
end

# 与えられたリソースに対応する統合テストを返す
def integration_tests(resource = :all)
  if resource == :all
    Dir["test/integration/*"]  else
    Dir["test/integration/#{resource}_*.rb"]
  end
end

# 与えられたリソースに対応するコントローラのテストを返す
def controller_test(resource)
  "test/controllers/#{resource}_controller_test.rb"
end

# 与えられたリソースに対応するすべてのテストを返す
def resource_tests(resource)
  integration_tests(resource) << controller_test(resource)
end

ここで行われていることは大雑把に下記のファイルをGuardがマッチング観測を行います。

テスト対象 テストコード
test/*/*_test.rb test/*/*_test.rb
test/test_helper.rb All test(全て)
config/routes.rb test/integration/*
app/models/*.rb test/models/*_test.rb
app/controllers/*_controller.rb リソースに対応するすべてのテスト
app/views/*.html.erb test/controllers/*_controller_test.rb +
test/integration/*
app/helper/*.helper.rb test/integration/*
app/views/layouts/application.html.erb test/integration/site_layout_test.rb
app/helpers/sessions_helper.rb test/integration/*+
test/helpers/sessions_helper_test.rb
app/controllers/sessions_controller.rb test/controllers/sessions_controller_test.rb+
test/integration/users_login_test.rb
app/controllers/account_activations_controller.rb test/integration/users_signup_test.rb
app/views/users/* test/integration/users_*.rb+
test/controllers/users_controller_test.rb+
test/integration/microposts_interface_test.rb

Guardfile中の

guard :minitest, spring: "bin/rails test", all_on_start: false do

で、GuardからSpringサーバを使用します。

Railsの開発効率をあげる - Springを使ってRailsのコンソールコマンドの実行を早くする - Rails Webook

SpringはRails4.1から標準で付属するようになったアプリケーションプリローダーで、前処理として必要なライブラリを事前にバックグランドでロードすることで、その待ち時間を短縮することができます。

integration testフォルダについて

Rails テスティングガイド | Rails ガイド

Rails結合テスト(integration test)は、アプリのtest/integrationディレクトリに作成します。Railsでは結合テストのスケルトンを生成するジェネレータが提供されています。

gitignore

最後にSpringとGitとの競合を防ぐために.gitignoreファイルにspringを追加します

# Ignore Spring files.
/spring/*.pid

どうやらSpringとGitと共存すると色々問題だそうです。

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう

Springサーバーは本節の執筆時点では若干不安定な点が残っていて、Springのプロセスが起動したまま多数残留すると、テストのパフォーマンスが低下してしまうことがあります。テストの実行が異常に遅くなってきたと感じたら、プロセスをチェックし、必要に応じてSpringをkillするとよいでしょう

結果

$bundle exec guard

でGuardを動かすことで、
テストコードやら、テスト対象コードを更新するとテストコードを自動で実施します。
また終了するにはCTRL + Dです

version

執筆時のversion

Gem Version
Rails 5.2.2
Minitest-reporters 1.1.14
guard 2.13.0
guard-minitest 2.4.4

参考

minitest-reporterの導入について
bunoacts.hatenablog.com

Springサーバについて

ruby-rails.hatenadiary.com