RSpec初期設定手順

# はじめに
Rails API×Next.jsでアプリを作成しています。
今回、バックエンドテストでRSpecを使うため、セットアップ手順をまとめます。

https://rspec.info/
# セットアップ手順
下記の手順を参考に進めていきます。

今回は、**私含めRailsを初めて触る方に向けて、ドキュメントで省かれているような説明も極力丁寧に行っていきます**。

https://github.com/rspec/rspec-rails

### 1．GemfileにRSpecの設定を追記

Gemfileの`group :development, :test do`に下記を追加してください。

**`rspec-rails`のバージョンは使っているRailsのバージョンにより異なるため、注意してください**

**バージョン参考**
>rspec-rails 7 supports Rails 7.0 to 7.2. For earlier versions of Rails, you should use rspec-rails-6 for Rails 6.1, rspec-rails-5 for Rails 5.2 and 6.0, rspec-rails-4 for Rails 5.x, and rspec-rails 3 for even older versions.

https://rspec.info/features/7-1/rspec-rails/

```gemfile
group :development, :test do
  gem 'rspec-rails', '~> 7.0.0'
  gem "debug", platforms: %i[ mri mingw x64_mingw ]
  # Factorybot追加(任意)
  gem 'factory_bot_rails'
end
```
なお、Factorybotは任意で追加してください。

**※Factorybotとは**
**テストデータの作成をサポートしてくれる機能**です。
本解説ではこちらを用いてテストを作成しています。
### 2．Factorybotの設定ファイル作成

**FactoryBotを使用しない方は本手順不要**です。

FactoryBotの設定をRSpecに組み込んでいきます。
`spec/support/factory_bot.rb`を作成します。
```rb:factory_bot.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end
```
### 3．RSpecインストール

まず、依存関係を更新します。
```
bundle install 
```
続いて、RSpecをインストールします。
```
rails generate rspec:install
```
実行後、以下の設定ファイルが作成されます。

`.rspec`
→ RSpec の設定ファイル（デフォルトで --require spec_helper が含まれる）
`spec/spec_helper.rb`
→ RSpec の基本設定ファイル
`spec/rails_helper.rb`
→ Rails に関する設定ファイル（spec_helper.rb を読み込む）

**※spec/ ディレクトリが作成されていない場合**
手動で作成してから再度 `rails generate rspec:install` を実行してください。

### 4．rails_helper.rb の設定を確認

**※1～5の項目を確認＆追記してください**

```rb:rails_helper.rb

# rspec-rails を使用するための設定※1
require 'spec_helper'
# テスト時に誤って本番や開発データベースを使用しないようにするための設定
ENV['RAILS_ENV'] ||= 'test'
# Railsの機能をRSpecで使用できるようにする
require File.expand_path('../config/environment', __dir__)

# RSpec の実行環境が production になっていないかチェック※2
abort("The Rails environment is running in production mode!") if Rails.env.production?

require 'rspec/rails'

# （FactoryBot）spec/support ディレクトリ内のすべてのファイルを読み込む※3
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  abort e.to_s.strip
end

# ※4
RSpec.configure do |config|
  fixtures
  config.fixture_path = Rails.root.join('spec/fixtures')
  # FactoryBot を使用するための設定
  config.include FactoryBot::Syntax::Methods
  # テストが DB を変更した場合にリセットする設定（RSpec の transactions を使用）
  config.use_transactional_fixtures = true

  # You can uncomment this line to turn off ActiveRecord support entirely.
  # config.use_active_record = false

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, type: :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://rspec.info/features/7-0/rspec-rails
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
  
  # 不要な `should` の警告を抑制※5
  config.expect_with :rspec do |expectations|
    expectations.syntax = :expect
  end
end
```

`RAILS_ENV` は、Rails の環境を切り替えるための変数です。
値が設定されていないときは test をセットしています。
これにより、テスト実行時に本番環境や開発環境のデータが誤って書き換えられるのを防ぎます。
### 5. モデルのテストファイルを作成

**※モデルを新規作成する場合**

Postモデルを作成する例
```
rails generate model post
```
**※モデル作成済みの場合**

`spec/models` 配下にテストファイルを作成していきます。

Postモデルがある場合：
```
rails generate rspec:model post
```
実行後`spec/models/post_spec.rb` が作成されます。
***
**～モデルとはどこを指すのか？～**

初学者だとわからないこともあるかと思います。

**まず`app/models`配下にrbファイルがあるかを確認**してください。
例えば`app/models/post.rb`のようなファイルになります。

次に、そのファイルの中を開いてください。
下記のようなクラス定義があれば、モデルが定義されていることになります。こちらはPostモデルの例です。
```
class Post < ApplicationRecord 
```
### 6. モデルのテストを記述
作成された spec/models/post_spec.rb にRSpecを使ったテストを記述します。
下記は一例です。
```rb:post_spec.rb
require 'rails_helper'

RSpec.describe Post, type: :model do
  
  it "タイトル、コンテンツ、ユーザー名があること" do
  post = Post.new(
    title: "title",
    content: "content",
    username: "username"
  )
  expect(post).to be_valid
  end

  it "タイトルがなければ無効であること" do
  post = Post.new(title: nil)
  post.valid?
  expect(post.errors[:title]).to include("can't be blank")
  end

  it "ユーザー名がなければ無効であること" do
  post = Post.new(username: nil)
  post.valid?
  expect(post.errors[:username]).to include("can't be blank")
  end

  it "重複したユーザー名があれば無効であること" do
  Post.create(
    title: "title",
    content: "content",
    username: "username"
  )
  post = Post.new(
    title: "title",
    content: "content",
    username: "username"
  )
  post.valid?
  expect(post.errors[:username]).to include("has already been taken")
  end
end
```
### 7.テスト実行
以下のコマンドをたたいてテストを実行します。
```
bundle exec rspec
```
特定のファイルだけ実行する場合：
```
bundle exec rspec spec/models/post_spec.rb
```
テストが通っていればRSpecのセットアップは完了です。お疲れさまでした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/9a75a8ef-2433-0e2e-5b96-98bba07259ae.png)


# おわりに
RSpecの設定方法を初学者向けに解説してみました。
私自身Railsを触り始めて一か月弱なので、どこに何が書かれていているのかを理解しながら慎重に進めています。
同じように学習を頑張る方の一助となれば幸いです。