ruby で作成中のプロジェクトに途中から RSpec, Guard, RuboCop を導入する（あえて手作業で）

# 目的

何らかの理由で RSpec や Guard, RuboCop などのテスト環境を導入していなかったプロジェクトに、途中から導入する（あえて手作業で）。

# 手順

## Gemfile 書き換え

Gemfile に以下を追加

``` ruby: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 する

```shell-session
$ bundle install
```

## rspec の初期化

```shell-session
$ rspec --init
  create   .rspec
  create   spec/spec_helper.rb
```

.rspec と spec/spec_helper.rb が生成される。
.rspec は、お好みで書き換える。

例）テスト結果をドキュメント形式で色付けして出力する設定。

```:.spec
--require spec_helper
--format documentation
--color
```

## guard の初期化

```shell-session
$ 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 の初期化

```shell-session
$ bundle exec guard init rubocop
hh:mm:ss - INFO - rubocop guard added to Guardfile, feel free to edit it
```

既存の Guardfile に新たなブロックが追加される。

```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 の出力をしないようにする。

```Guardfile
# 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 のチェックを停止・スキップさせることも可能。

現状のコーディング規約違反（と判定されている部分）を書き出して、無視するようにする。

```shell-session
$ 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.
```

出力の最後の２行に書かれているのが

- `.rubocop_todo.yml` ファイルが生成された。
- `rubocop --config .rubocop_todo.yml` を実行するか、`.rubocop.yml`ファイルに `inherit_from: .rubocop_todo.yml` を追記せよ。

みたいなこと（意訳）。

その通りに実施する。

```shell-session
$ echo "inherit_from: .rubocop_todo.yml" >> .rubocop.yml
```

再度テストしてみると

```shell-session
$ bundle exec rubocop

XX files inspected, xx offense detected
```

規約違反とされる数が激減している（はず）。

なぜか、今回試したプロジェクトでは規約違反が「なくなって見える」わけではなかった。環境やプロジェクトによっても違うはず。
（もしくは、単純にコーディング規約に違反している。）

あとは、`rubocop_todo.yml` ファイルや `.rubocop.yml` ファイルの中身を、プロジェクトのコーディング規約に合わせて修正していく。

## テストを書く

テストを書いていく。


# まとめと蛇足

## IDE を利用したコーディング規約のチェック

IDE によっては、コードの入力時に自動補完やコーディングチェックなどが実施されるものもあるが、素のシェル環境や vi でちょこっとだけ修正かける場合にも、コーディング規約のチェックができるという意味で、RuboCop は導入していた方が良いと感じた。
「コーディング規約そのものを明文化しておく」という品質担保の一貫として考えると良い。

## gem のプラグイン一括初期化など

RSpec や Guard のように汎用性のある gem はプラグインなども豊富で、一括して初期化することもできる。
あえて一段階ずつ実行することで、コマンドの基本動作・思想やまとめる意義を発見できる気がする。

## 仮想化・コンテナ技術を使ったテンプレート化

そもそも「テストを書かないで始めるプロジェクト」というのがよろしくない（反省）。
「**レガシーコードとは、単にテストのないコードである**」という考え方もかなり浸透しているように感じる。

小さなプロジェクトや、パッと思いついたことを試したい時にでも、上記のような流れをするのは、正直言って面倒臭い（反省）。

ただ、GitHub や docker （コンテナ化）などの技術・サービスをうまく利用すれば、「テスト環境が整ったプロジェクトのテンプレート化」やそのテンプレートをコマンド一つ（？）で導入することは可能になるので、積極的に利用した方が良い。

というか、そのための技術・サービスだよね。

# 参照

- [はじめてのRSpec - まずテスト書いてからコード書くシンプルなチュートリアル - Qiita](http://qiita.com/luckypool/items/e3662170033347510c3c)

- [guard/guard - GitHub](https://github.com/guard/guard)
- [Guardでrspecのテストを自動化する - Shoyan blog](https://shoyan.github.io/blog/2016/05/24/introduce-guard-gem-and-guard-rspec/)
- [Railsの開発効率を上げる - guard-rubocopを使ってRailsで自動で静的コード解析ツール(RuboCop)を実行させる - Rails Webook](http://ruby-rails.hatenadiary.com/entry/20141019/1413698128)