初めてのSystemSpecでつまづいたところメモ

##はじめに
初学者で、初めてRSpecを記載した際につまづいたところ、今後意識しておきたいところを忘れないように自分用にメモに残します。
Qiita投稿も初めてでマークダウンすらままなりませんので間違い等あるかと思いますが、誤りやもっとこうした方が、という箇所あれば教えていただければと思います。
##使用した機能
テストフレームワーク：　RSpec
Webアプリ用のE2Eテスティングフレームワーク。Web アプリのテストを書きやすくする語彙を提供してくれるgem：Capybara
データの作成：　FactoryBot

##項目
1. fill_in の書き方
1. FactoryBotの作られるタイミング
2. テストを実行してエラーが起こったとき

###fill_in の書き方
* fill_in 'Email'のようにViewに表記されているものを記載するのではなく、
fill_in `'user[email]'`のように記載する。（fill_in 'Email'で記載していたところ、Viewに該当文字はあるはずなのにエラーになりました。。）
    * 検証ツールで対象箇所を選択し、inputタグのnameの中に記載されているもの。（Viewが他の言語表記になった際に書き直さなくてもいいように等）
 
>  参考リンク　https://qiita.com/pooooon/items/4fbc429d07e4b65ed928
  
```ruby:spec/system/users_spec.rb
#例として下記をあげます
describe 'ログイン前' do
   describe '新規登録機能'do
     context '入力値が正しい'do
       it '新規登録ができる'do
         visit new_user_registration_path
         fill_in 'user[name]',with: user_a.name
         fill_in 'user[email]', with: user_a.email
         fill_in 'user[password]',with: 'password'
         fill_in 'user[password_confirmation]',with: 'password'
         click_button '上記内容で登録する'
         expect(page).to have_content 'アカウント登録が完了しました。'
       end
     end
  end
end
```


### FactoryBotの作られるタイミング
 `create`は、作成してデータも保存される。
 `build`は、作成するがデータは保存されない。
 ユーザーの新規登録のテストでは、`create`でユーザーを作成した後にユーザーを作成しようとすると重複して作成不可、エラーになるため、`build`で作成する。

 
```
 let!(:user_a){FactoryBot.build(:user, name: 'ユーザーA', email: 'a@example.com')}
 let!(:user_b){FactoryBot.create(:user, name: 'ユーザーB', email: 'b@example.com')}
 let!(:user){FactoryBot.create(:user)}
 ```

###テストを実行してエラーが起こったとき
 `tmp/screen`の中にスクリーンショットが取られているのでエラー文確認して該当ファイルを開いてみると良い。
  ユーザーテストの場合、そもそもログインができていないのか、その先のテストが実行したけど失敗しているのか等の見当がつけられる。

###今回記載したUser周りのテスト
```ruby:spec/system/users_spec.rb
require 'rails_helper'

describe 'User管理機能', type: :system do
 let!(:user_a){FactoryBot.build(:user, name: 'ユーザーA', email: 'a@example.com')}
 let!(:user_b){FactoryBot.create(:user, name: 'ユーザーB', email: 'b@example.com')}
 let!(:user){FactoryBot.create(:user)}
  describe 'ログイン前' do
    describe '新規登録機能'do
      context '入力値が正しい'do
        it '新規登録ができる'do
          visit new_user_registration_path
          fill_in 'user[name]',with: user_a.name
          fill_in 'user[email]', with: user_a.email
          fill_in 'user[password]',with: 'password'
          fill_in 'user[password_confirmation]',with: 'password'
          click_button '上記内容で登録する'
          expect(page).to have_content 'アカウント登録が完了しました。'
        end
      end
      context 'メールが空白'do
        it '新規登録に失敗する'do
          visit new_user_registration_path
          fill_in 'user[name]',with: user_a.name
          fill_in 'user[email]', with: ''
          fill_in 'user[password]',with: 'password'
          fill_in 'user[password_confirmation]',with: 'password'
          click_button '上記内容で登録する'
          expect(current_path).to eq '/users'
          expect(page).to have_content 'Eメールを入力してください'
        end
      end
      context 'メールが重複している' do
        it '新規登録に失敗する' do
          visit new_user_registration_path
          fill_in 'user[email]',with: user.email
          fill_in 'user[password]',with: 'password'
          click_button '上記内容で登録する'
          expect(page).to have_content 'Eメールはすでに存在します'
        end
      end
    end
    describe 'ログイン機能'do
      context 'ログインの入力値が正しい'do
        it 'ログインが成功する' do
          visit user_session_path
          fill_in 'user[email]',with: user.email
          fill_in 'user[password]',with: 'password'
          click_button 'Log in'
          expect(page).to have_content 'ログインしました'
        end
      end
      context 'パスワードが空白' do
        it 'ログインに失敗する' do
          visit user_session_path
          fill_in 'user[email]',with: user.email
          fill_in 'user[password]',with: ''
          click_button 'Log in'
          expect(current_path).to eq user_session_path
        end
      end
    end
  end
  describe 'ログイン後'do
    # モジュールに切り出したログインメソッド呼び出し
    before {login(user)}
    describe '編集機能'do
      context '入力値が正しい'do
        it 'ユーザ情報の編集に成功する'do
          visit edit_user_path(user)
          fill_in 'user[introduction]',with: 'よろしくお願いします！'
          click_button '変更を保存する'
          expect(page).to have_content 'プロフィールを編集しました。'
        end
      end
    end
  end
end
```