Rails チュートリアル（３章、４章、５章）をRSpecでテスト

#はじめに
Rails チュートリアルのテストを書いて見ました。

追加しました。
[Rails チュートリアル（6章）をRSpecでテスト](https://qiita.com/sakakinn/items/e7f8115c3bd8fc6053e5)
[Rails チュートリアル（7章）をRSpecでテスト](https://qiita.com/sakakinn/items/41c0f39152c3713fefc4)
[Rails チュートリアル（8章）をRSpecでテスト](https://qiita.com/sakakinn/items/b54e9181634b34383d98)

#Rails チュートリアル　３，４章
#RSpecの導入
gemを入れます。

```rb:gemfile

group :development, :test do
  gem 'rspec-rails', '~> 3.8'
end
```
```
$ bundle install
```
```
$ rails generate rspec:install
```
DBを作成していなければ、`rails db:create`で作成してください。作ってなく警告が出ました。

#RSpecの設定

以下を参考にしました。↓
[RailsでRSpecの初期設定を行う際のテンプレートを作ってみる-Qiita](https://qiita.com/yuta-ushijima/items/ffb34823b8bba2180c94)


```rb:.rspec
--require rails_helper
--format documentation
```

```rb:config/application.rb
module SampleApp
  class Application < Rails::Application
    config.load_defaults 5.2
#----------ここから下を追加---------------------------
    config.generators do |g|
      g.test_framework :rspec,
                       helper_specs: false,
                       routing_specs: false,
                       view_specs: false,
                       controller_specs: false
    end
#----------ここまで-----------------------------------
    config.generators.system_tests = nil
  end
end
```
RSpecを利用したコントローラの機能テストは、Rails5からはrequest specで記述することが推奨されてるみたいなので、controller_specsも省きました。

以下を参考にしました。↓
[Rails5でコントローラのテストをController specからRequest specに移行する-Qiita](https://qiita.com/t2kojima/items/ad7a8ade9e7a99fb4384)
[everydayrails](https://everydayrails.com/2016/08/29/replace-rspec-controller-tests.html)
[Project: RSpec Rails 3.8](https://relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec)


#テストを書く(３章、4章）

###static_pagesコントローラーのテスト
４章のテストを書いてます。元のテスト↓
[4.1.2 カスタムヘルパー　-Ruby on Rails チュートリアル](https://railstutorial.jp/chapters/rails_flavored_ruby?version=5.1#sec-custom_helpers)

```rb:spec/requests/access_to_static_pages_spec.rb

require 'rails_helper'

RSpec.describe 'Access to static_pages', type: :request do
  context 'GET #home' do
    before { get root_path }
    it 'responds successfully' do
      expect(response).to have_http_status 200
    end
    it "has title 'Ruby on Rails Tutorial Sample App'" do
      expect(response.body).to include 'Ruby on Rails Tutorial Sample App'
      expect(response.body).to_not include '| Ruby on Rails Tutorial Sample App'
    end
  end
  context 'GET #help' do
    before { get help_path }
    it 'responds successfully' do
      expect(response).to have_http_status 200
    end
    it "has title 'Home | Ruby on Rails Tutorial Sample App'" do
      expect(response.body).to include 'Help | Ruby on Rails Tutorial Sample App'
    end
  end
  context 'GET #about' do
    before { get about_path } 
    it 'responds successfully' do
      expect(response).to have_http_status 200
    end
    it "has title 'Home | Ruby on Rails Tutorial Sample App'" do
      expect(response.body).to include 'About | Ruby on Rails Tutorial Sample App'
    end
  end
end

```
以上で３章と４章のテストが完了です。
5章で変更するルートはここで変更してしまってます。
また、contactアクションをつくることになってますが、省いてます。

request specのファイル名はなんて書けばいいかわからず、なんとなくで書いてしまいました。

#Railsチュートリアル　５章

5章のルートのテストは４章でついで書いてしまったので、残りのレイアウトのテストを書きます。

#system specの準備
```rb:gemfile
+ gem 'capybara'
+ gem 'webdrivers'
- #gem 'chromedriver-helper' #削除
```
```
$ bandle install
```
```rb:spec/spec_helper.rb

require 'capybara/rspec' #これも追加

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
#-------------ここから追加-----------------------------
  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless
  end
#-------------ここまで--------------------------------
end
```
最後にspecフォルダーにrequestsフォルダーを作り、その中にテストファイルを作ります。

#テストを書く（５章）
###site_layoutのテスト
ホームページのリンクのテストを書きます。

元のテスト↓
[5.3.4 リンクのテスト -Ruby on Railsチュートリアル](https://railstutorial.jp/chapters/filling_in_the_layout?version=5.1#sec-layout_link_tests)

```rb:systems/site_layout_spec.rb

require 'rails_helper'

RSpec.describe 'site layout', type: :system do
  context 'access to root_path' do
    before { visit root_path }
    subject { page }
    it 'has links sach as root_path, help_path and about_path' do
      is_expected.to have_link nil, href: root_path, count: 2
      is_expected.to have_link 'Help', href: help_path
      is_expected.to have_link 'About', href: about_path
    end
  end
end
```

一つのページにリンクがそろっているかのテストなので、itで分けませんでした。正しいかはわかりません。

###application_helperのテスト
次に以前書いたタイトルテストをリファクタリングします。テストでも`full_title`ヘルパーを使います。

元のテスト↓
[演習　-Ruby on Railsチュートリアル](https://railstutorial.jp/chapters/filling_in_the_layout?version=5.1#sec-exercises_layout_link_tests)

```rb:spec/spec_helper.rb

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless
  end
  config.include ApplicationHelper #追加
end
```
```rb:spec/requests/access_to_static_pages_spec.rb

require 'rails_helper'

RSpec.describe 'Access to static_pages', type: :request do
  context 'GET #home' do
    before { get root_path }   
    it 'responds successfully' do
      expect(response).to have_http_status 200
    end
    it "has title 'Ruby on Rails Tutorial Sample App'" do
      expect(response.body).to include full_title('') #変更部分
      expect(response.body).to_not include '| Ruby on Rails Tutorial Sample App'
    end
  end

  context 'GET #help' do
    before { get help_path } 
    it 'responds successfully' do
      expect(response).to have_http_status 200
    end
    it "has title 'Home | Ruby on Rails Tutorial Sample App'" do
      expect(response.body).to include full_title('Help') #変更部分
    end
  end

  context 'GET #about' do
    before { get about_path }
    it 'responds successfully' do
      expect(response).to have_http_status 200
    end
    it "has title 'Home | Ruby on Rails Tutorial Sample App'" do
      expect(response.body).to include full_title('About') #変更部分
    end
  end
end
```

次にapplication_helperのテストを書きます。（`full_title`ヘルパーのテストです）
specフォルダーにhelpersフォルダーを作成し、その中にテストファイルを作ります。

```rb:helpers/application_helper_spec.rb

require 'rails_helper'

RSpec.describe ApplicationHelper, type: :helper do
  describe '#full_title' do
    it { expect(full_title('')).to eq 'Ruby on Rails Tutorial Sample App' }
    it { expect(full_title('Help')).to eq 'Help | Ruby on Rails Tutorial Sample App' }
  end
end
```

###usersコントローラーのテスト
元のテスト↓
[5.4.1 Usersコントローラ -Ruby on Railsチュートリアル](https://railstutorial.jp/chapters/filling_in_the_layout?version=5.1#sec-users_controller)

```rb:requests/access_to_users_spec.rb

require 'rails_helper'

RSpec.describe 'access to users', type: :request do 
  describe 'GET #new' do
    it 'responds successfully' do
      get signup_path
      expect(response).to have_http_status 200
    end
  end
end
```

###site_layoutのテスト(signupページについて)

元のテスト↓
[演習　-Usersコントローラ -Ruby on Railsチュートリアル](https://railstutorial.jp/chapters/filling_in_the_layout?version=5.1#sec-exercises_signup_url)

```rb:systems/site_layout_spec.rb

require 'rails_helper'

RSpec.describe 'site layout', type: :system do
  #上記省略

  context 'access to signup_path' do
    before { visit signup_path }
    subject { page }
    it "has 'Sign up' contens and includes 'Sign up' at title" do
      is_expected.to have_content 'Sign up'
      is_expected.to have_title full_title('Sign up')
    end
  end
end
```

ここまで５章が終わりです。