SystemSpec導入と書き方

# はじめに
- [railsでアプリケーションを立ち上げたらすること](https://qiita.com/smbbc20/items/4953a708e752cc806b93)
- [RailsでFlashメッセージを表示させる](https://qiita.com/smbbc20/items/952a33501343614f197f)
- [Railsのvalidateを自作する](https://qiita.com/smbbc20/items/39b457aec58ca22d6398)
- [railsでログイン機能実装](https://qiita.com/smbbc20/items/b2d21c0b21ad3658b32b)

これまでに引き続き、[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4-ebook/dp/B07JHQ9B5T)のアウトプットを投稿します！
今回はrspecについてです！
タスク管理アプリケーションを例に進めていきます。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [Rspecの準備](#Chapter1)
1. [Specの書き方](#Chapter2)
1. [FactoryBotでテストデータを作成](#Chapter3)
1. [テストを書く](#Chapter4)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# Rspecの準備
・gemをインストール
Gemfileの
`group :development, :test do`のブロックに以下を追記します。

```Gemfile
gem 'rspec-rails', '~> 3.7'
```

記述後`bundle install`でgemをインストールします。完了したら、以下のコマンドを実行し、RSpecに必要なディレクトリや設定ファイルを作成します。

```
rails g spec:install
```

・testディレクトリ削除
`rails new`でアプリケーションを立ち上げた時に自動で作成されるtestディレクトリを削除します。なぜなら、Rspecのファイルは、specディレクトリの中に作成するからです。

```
rm -r ./test
```

・Capybaraを使うためにspec_helper.rbを編集
Capybaraは`rails new`をした際にインストールされているため、`機能の読み込み`と`実行するドライバの設定`を記述します。

```spec/spec_helper.rb
require 'capybara/spec'
config.before(:each, type: :system) do
  driven_by :selenium_chrome_headless
end
```

・FactoryBotのインストール

Gemfileの
`group :development, :test do`のブロックに以下を追記します。

```Gemfile
gem 'factory_bot_rails', '~> 4.11'
```

<a id="#Chapter2"></a>
# Specの書き方
ここでは、タスク管理アプリケーションの一覧表示に関するテストを例にします。

```tasks_spec.rb
describe '一覧表示機能' do
  context 'Aさんがログインしているとき' do
    before do
      # テスト条件を満たすよう処理を記述する
    end
    it 'Aさんの投稿だけが表示される' do
      # 期待する動作を記述する
    end
  end
end
```

上記の例では条件が一つですが、複数ある場合はcontextをネストすることもできます。

<a id="#Chapter3"></a>
# FactoryBotでテストデータを作成
`spec/factories/users.rb`を作成し、Userモデルのデータを記述します。

```spec/factories/users.rb
FactoryBot.define do
  factory :user do
    name { 'テストユーザー' }
    email { 'test@example.com' }
    password { 'password' }
  end
end
```

`factory :user`の記述で、railsがUserモデルのテストデータだなと、解釈してくれます。もし、違う名前をつけたいときは、以下のようにclassを明記します。

```
factory :test_user, class: User do
```

次にいま作成したユーザーに紐づく投稿データを作成します。先程と同様に、`spec/factories/tasks.rb`を作成します。

```spec/factories/tasks.rb
FactoryBot.define do
  factory :task do
    name { 'テストを作成する' }
    description { '必要なものをインストールし、作成する。' }
    user
  end
end
```

上記の`user`は、先ほど作成した`:user`のデータに紐づくものと定義しています。こちらも、モデル名と違うテストデータを紐付けるときは`user`の箇所を以下のように書きます。

```
association :user, factory: :admin_user
```

<a id="#Chapter4"></a>
# テストを書く
まずは、日本語で枠組みを作成していきます。

```spec/system/tasks_spec.rb
require 'rails_helper'
describe '一覧表示機能' do
  before do
    # ユーザーAを作成する
    # ユーザーAのタスクを作成する
  end
  context 'ユーザーAがログインしているとき' do
    before do
      # ユーザーAでログイン
      # ログイン画面に遷移
      # メールアドレスを入力
      # パスワードを入力
      # ログインボタンを押す
    end
    it 'ユーザーAが作成したタスクが表示される'
      # 作成されたタスクが表示されている
    end
  end
end
```

テストの枠組みができたら、実際にテストコードを書いていきます！

```spec/system/tasks_spec.rb
require 'rails_helper'
describe '一覧表示機能' do
  before do
    # ユーザーAを作成する
    user_a = FactoryBot.create(:user)
    # ユーザーAのタスクを作成する
    FactoryBot.create(:task, name: "最初のタスク", user: user_a)
  end
  context 'ユーザーAがログインしているとき' do
    before do
      # ユーザーAでログイン
      # ログイン画面に遷移(ログイン画面のpathにvisit)
      visit login_path
      # メールアドレスを入力(labelの名称を指定します)
      fill_in 'メールアドレス', with: 'a@example.com'
      # パスワードを入力(labelの名称を指定します)
      fill_in 'パスワード', with: 'password'
      # ログインボタンを押す
      click_botton 'ログインボタン'
    end
    it 'ユーザーAが作成したタスクが表示される'
      # 作成されたタスクが表示されている
      expect(page).to have_content '最初のタスク'
    end
  end
end
```

<a id="#reference"></a>
# 参考文献
- [現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4-ebook/dp/B07JHQ9B5T)