目的
何らかの理由で RSpec や Guard, RuboCop などのテスト環境を導入していなかったプロジェクトに、途中から導入する(あえて手作業で)。
手順
Gemfile 書き換え
Gemfile に以下を追加
group :development, :test do
gem 'rake'
gem 'rspec'
gem 'rspec-core'
gem 'guard-rspec'
gem 'terminal-notifier'
gem 'terminal-notifier-guard'
gem 'rubocop'
gem 'rubocop-rspec'
gem 'guard-rubocop'
end
bundle install する
$ bundle install
rspec の初期化
$ rspec --init
create .rspec
create spec/spec_helper.rb
.rspec と spec/spec_helper.rb が生成される。
.rspec は、お好みで書き換える。
例)テスト結果をドキュメント形式で色付けして出力する設定。
--require spec_helper
--format documentation
--color
guard の初期化
$ bundle exec guard init rspec
hh:mm:ss - INFO - Writing new Guardfile to /PATH/TO/PROJECT/Guardfile
hh:mm:ss - INFO - rspec guard added to Guardfile, feel free to edit it
Guardfile が生成される。
素の ruby プロジェクトだと rails 関連のテストは不要なので削除しておく。
RuboCop の初期化
$ bundle exec guard init rubocop
hh:mm:ss - INFO - rubocop guard added to Guardfile, feel free to edit it
既存の Guardfile に新たなブロックが追加される。
# ~~ ここまで既存の Guardfile の内容
# 以下の内容が追記される
guard :rubocop do
watch(%r{.+\.rb$})
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
end
RuboCop の設定修正
rspec 失敗時の RuboCop スキップ
そのままの設定だと、 rspec のテストが失敗した時にも RuboCop の出力が続いて、テスト結果が見にくくなる。
そこで、rspec が失敗したら RuboCop の出力をしないようにする。
# RSpecが失敗したら、RuboCopをスキップする
#
# http://ruby-rails.hatenadiary.com/entry/20141019/1413698128
group :red_green_refactor, halt_on_fail: true do
guard :rspec do
...
end
guard :rubocop do
...
end
end
コーディング規約の最適化
RuboCop 標準のコーディング規約ではキツイ・ユルイという場合や、プロジェクトのコーディング規約が違う場合に、RuboCop のチェックを停止・スキップさせることも可能。
現状のコーディング規約違反(と判定されている部分)を書き出して、無視するようにする。
$ bundle exec rubocop --auto-gen-config
~~ (結果が出力される)
Created .rubocop_todo.yml.
Run `rubocop --config .rubocop_todo.yml`, or add `inherit_from: .rubocop_todo.yml` in a .rubocop.yml file.
出力の最後の2行に書かれているのが
-
.rubocop_todo.yml
ファイルが生成された。 -
rubocop --config .rubocop_todo.yml
を実行するか、.rubocop.yml
ファイルにinherit_from: .rubocop_todo.yml
を追記せよ。
みたいなこと(意訳)。
その通りに実施する。
$ echo "inherit_from: .rubocop_todo.yml" >> .rubocop.yml
再度テストしてみると
$ bundle exec rubocop
XX files inspected, xx offense detected
規約違反とされる数が激減している(はず)。
なぜか、今回試したプロジェクトでは規約違反が「なくなって見える」わけではなかった。環境やプロジェクトによっても違うはず。
(もしくは、単純にコーディング規約に違反している。)
あとは、rubocop_todo.yml
ファイルや .rubocop.yml
ファイルの中身を、プロジェクトのコーディング規約に合わせて修正していく。
テストを書く
テストを書いていく。
まとめと蛇足
IDE を利用したコーディング規約のチェック
IDE によっては、コードの入力時に自動補完やコーディングチェックなどが実施されるものもあるが、素のシェル環境や vi でちょこっとだけ修正かける場合にも、コーディング規約のチェックができるという意味で、RuboCop は導入していた方が良いと感じた。
「コーディング規約そのものを明文化しておく」という品質担保の一貫として考えると良い。
gem のプラグイン一括初期化など
RSpec や Guard のように汎用性のある gem はプラグインなども豊富で、一括して初期化することもできる。
あえて一段階ずつ実行することで、コマンドの基本動作・思想やまとめる意義を発見できる気がする。
仮想化・コンテナ技術を使ったテンプレート化
そもそも「テストを書かないで始めるプロジェクト」というのがよろしくない(反省)。
「レガシーコードとは、単にテストのないコードである」という考え方もかなり浸透しているように感じる。
小さなプロジェクトや、パッと思いついたことを試したい時にでも、上記のような流れをするのは、正直言って面倒臭い(反省)。
ただ、GitHub や docker (コンテナ化)などの技術・サービスをうまく利用すれば、「テスト環境が整ったプロジェクトのテンプレート化」やそのテンプレートをコマンド一つ(?)で導入することは可能になるので、積極的に利用した方が良い。
というか、そのための技術・サービスだよね。