RailsアプリにRSpecを導入する手順

##はじめに
RSpecはRubyのテストフレームワークです。これ以外にMinitestというものがありますが、実際の現場では、RSpecが使われることが多いようなので導入する手順をメモしておきます。

環境
Widows 10
cloud9

##RSpecをインストール

**gemを追加**
最近はsystemスペックの利用が推奨されています。systemスペックは、バージョンが3.8.0以上である必要があるためそれをインストールしましょう。

```rb:Gemfile
group :development, :test do
 gem 'rspec-rails' # バージョン指定する必要があるかも'~> 3.8.0' 
end
```

```rb
$ bundle install
```
RSpecをインストールする

```rb
$ rails generate rspec:install
```
必須ではないが、RSpec の出力をデフォルトの形式から読みやすいドキュメント形式に変更できる。やっといたほうが見た目が良くなるのでおすすめです。

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

**テストを速くする**
このgemを追加するとSpringにより、テストスイートが速くなる。必要だと思ったら入れてください。

```rb:Gemfile
group :development do
  gem 'spring-commands-rspec'
end

# bundle installを忘れずに！
```
そしたら、以下のコマンドを実行して下さい。

```rb:
$ bundle exec spring binstub rspec
```
そしてこれからは、RSpecのコマンドを打つ際先頭に、bin/をつけるようにしましょう。

**ジェネレータ**
rails g する際に一緒にスペックファイルも生成されるようにする。また、あまり使うことのないファイルは生成されないようにします。コードが複雑になってきたら使うかもしれないので、その時は削除していってください。

```rb:config/application.rb 
.
.
module Sample
  class Application < Rails::Application

     config.generators do |g|
       g.test_framework :rspec,
         fixtures: false, # factory_bot_railsを使うなら削除してください
         view_specs: false,
         helper_specs: false,
         routing_specs: false
    end

  end
end
```
これで基本的なセットアップは終了です！
##便利なgem
ここからはRSpecを使っていく際に便利なgemを紹介します。最新のものを使うようにしましょう。

```rb:Gemfile
group :development, :test do
  gem 'factory_bot_rails' # テストのサンプルデータを生成できる
end

group :test do
  gem 'capybara' #統合テスト(system)をするのに必要
  gem 'launchy' # save_and_open_page をスペック内で呼びだしたときに、HTMLを自動的に開く
  gem 'webdrivers' # js付きののテストができるようになる。
end

```

**Capybaraのセットアップ**
Capybaraを読み込めるように、requireする。

```rb:spec/rails_helper.rb
# その他の設定
require 'capybara/rspec'
```

**Capybaraで、JavaScriptを使ったテスト**

1 設定ファイルを書く
rails_helper.rbに直接書いてもいいが、今後設定が多くなってくると見にくくなるので、独立したファイルに設定を書いていきます。

```rb:spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } #このコメントアウトを外す。
```
これで、supportディレクトリ下にあるファイルを読み込めるようになる。このディレクトリを作り、そこにcapybara.rbというファイルを生成し、設定を書きます。

```rb:spec/support/capybara.rb
Capybara.javascript_driver = :selenium_chrome
or
Capybara.javascript_driver = :selenium_chrome_headless # ヘッドレスモードを使いたい場合
```

2 gemを追加
webdriversは、selenium-webdriver も一緒にインストールしてくれるので、selenium-webdriver がある場合は削除しといてください。

```rb:Gemfile
gem 'webdrivers'
```
これで、js: trueオプションをつけることで、JavaScript付きのテストができる。

**cloud9でヘッドレスモードを使えるようにする**
僕は今、cloud9を使っているので、ここで使えるようにしていきます。cloud9では、ヘッドレスモードしかできないみたいです。

1 Chromeブラウザをインストール
初期のAWSは、Chromeがインストールされてないのでインストールする。

```
$ curl https://intoli.com/install-google-chrome.sh | bash
```
2 ヘッドレスモードにする

```rb:spec/support/capybara.rb
Capybara.javascript_driver = :selenium_chrome_headless
```
3 selenium-webdriverとcapybaraを最新版にする

```
$ bundle update selenium-webdriver capybara
```
##Deviseのヘルパーメソッドを使えるようにする
これを記述することで、コントローラー、システム、リクエストスペックでDeviseのヘルパーメソッドである、**sign_in**が使えるようになる。
また、リクエストスペックの場合、Deviseのヘルパーメソッド使うために、少し設定が必要。

```rb:spec/rails_helper.rb
# その他の設定
RSpec.configure do |config|
  # その他の設定
  config.include Devise::Test::ControllerHelpers, type: :controller 
  config.include Devise::Test::IntegrationHelpers, type: :system
  config.include RequestSpecHelper, type: :request
end
```
**リクエストスペックの追加設定**
新しいファイルを作って設定を記述。

```rb:spec/support/request_spec_helper.rb
module RequestSpecHelper
  include Warden::Test::Helpers

  def self.included(base)
    base.before(:each) { Warden.test_mode! }
    base.after(:each) { Warden.test_reset! }
  end

  def sign_in(resource)
    login_as(resource, scope: warden_scope(resource))
  end

  def sign_out(resource)
    logout(warden_scope(resource))
  end

 private

  def warden_scope(resource)
    resource.class.name.underscore.to_sym
  end
end
```