【Rails】RSpecの導入手順（メモ）

# はじめに
チーム開発でテストツールとしてRSpecを導入することになったので調べたことを記録したいと思います。

# 環境
Ruby 3.0.3
Rails 6.1.4
rspec-rails 5.0.2
spring-commands-rspec 1.0.4

## 1. 必要モジュールのインストール
* RSpecをRailsアプリで使用するためには`rspec-rails`というgemが必要です。
* また必須ではありませんが、RSpecのテストをより高速に実行するために`spring-commands-rspec`もインストールしておきます。
* Railsのgeneratorを使用するためインストールグループはtest環境だけでなくdevelopment環境も指定する
<details><summary>test環境のみ指定した場合の挙動を確認</summary><div>
test環境のみを指定して`$ rails g ---`を試してみると、以下のように Test::Unit と Fixture のファイルが作成されてしまい、specファイル、factoriesファイル等は作成されない。

```
$ rails g model user name:string
Running via Spring preloader in process 28049
Expected string default value for '--jbuilder'; got true (boolean)
      invoke  active_record
      create    db/migrate/2021....._create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
```

development 環境でも使用できるようにした場合、デフォルトのtestディレクトリからspecディレクトリに RSpec のファイル生成され、test/fixturesの代わりに factory_bot のspec/factoriesが生成されるようになる。

```
$ rails g model user name:string
Running via Spring preloader in process 31740
Expected string default value for '--jbuilder'; got true (boolean)
      invoke  active_record
      create    db/migrate/2021....._create_users.rb
      create    app/models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
      invoke      factory_bot
      create        spec/factories/users.rb
```
</div></details>

```ruby:Gemfile
group :development, :test do
  gem 'rspec-rails'
  gem 'spring-commands-rspec'
end
```
* bundle installでGemfileに記載したgemをインストールします

```
$ bundle install
```

## 2. spring-commands-rspecの設定
以下を実行して`bin/rails`が使用できるように設定します

```bash
$ bundle exec spring binstub rspec
```

## 3. RSpecの設定
### 3-1. 以下のコマンドを実行して必要ファイルを生成します。
```bash
$ rails g rspec:install

# 以下のファイルが生成される
create  .rspec
create  spec
create  spec/spec_helper.rb
create  spec/rails_helper.rb
```

#### 生成されたディレクトリ、ファイルの役割は以下の通りです。
* `.rspec`
    * 基本設定ファイル
* `spec`
    * specディレクトリ配下にあるテストファイルがテストとして実行される
* `spec/spec_helper.rb`
    * Rspecの全体的な設定を記述するファイル
* `spec/rails_helper.rb`
    * Rails特有の設定を記述するファイル

### 3-2. .rspecの編集

```txt:.rspec
--require spec_helper
--format documentation # 追加
```

* `--require spec_helper`
    * デフォルトで記述されており、これから作成するspecファイルで毎回`require '--spec_helper'`と記述する必要がなくなる
* `--format documentation`
    * 記述することで、テストコードの実行結果をターミナル上に可視化してくれる
* 他にもテスト結果を色付けしてくれる`--color`など様々なオプションが用意してある

### 3-3. 動作確認
今回は簡易的にPostというモデルのオブジェクトを生成したとき中身がnilにならないことをテストしたいと思います.


```ruby:spec/models/post_spec.rb
require 'rails_helper' # 設定ファイルrails_helper.rbを読み込むコードが全テストにあります

RSpec.describe Post, type: :model do
  it "Postモデルをnewしたとき, nilでないこと" do
    expect(Post.new).not_to eq(nil)
  end
end
```
テストを実行します

```bash
$ bin/rails spec
```
しっかりとテストできていることが確認できます。

# その他
## `$ rails g [command] ~`と`$ rails g rspec:[command] ~`の違い
* `$ rails g [command] ~`
    * RSpecをインストールした時点で`rails g model Post`を実行すると以下のようにマイグレーションファイルやモデルファイルに加えてRSpec用のテストファイルを生成してくれる
    * デフォルトで生成されていたminitest用のテストファイルは生成されなくなる

```bash
$ rails g model post

invoke  active_record
create    db/migrate/20220110190849_create_posts.rb
create    app/models/post.rb
invoke    rspec
create      spec/models/post_spec.rb # <- モデルのspecファイルが生成される
```

* `$ rails g rspec:[command] ~`
    * `rails g rspec:model Post`を実行するとマイグレーションファイルやモデルファイルは生成されず、RSpec用のテストファイルのみ生成される
    * 開発の途中でRSpecを導入したりする際など、すでにモデルが存在する場合に使うとよい
   
```bash
$ rails g rspec:model post

create  spec/models/post_spec.rb
```

# 参考
https://github.com/rspec/rspec-rails

https://norix.tokyo/rspec/282/

https://qiita.com/yamaday0u/items/c3bf6036e11298771a99