超初学者 RSpecあるある早く言いたい〜

# はじめに
- どうも、プログラミングスクールにてRuby on Railsを勉強している、ななみんです。
未経験からのエンジニア転職に向けて今年の4月から学習を始めて、現在６ヶ月経ちました。

# 概要
- `Ruby`における`BDD`(Behaviour-Driven-Development:振舞駆動開発者)のためのテスティングフレームワーク`RSpec`の特に`System spec`を中心に書いています。
- スクールの課題の中で、RSpecを度々書く機会があるが、毎回新鮮な気持ちで取り組んでしまっています。（ぜーんぜん慣れない）
- 今回は、なかなか慣れてくれない自分へのメモも兼ねて、ひとまず２つ、RSpecあるあるとその対策を記事にまとめてみました。
※　内容はかなり初歩の初歩です！　

::: note warn
注意 　💡 誤った知識を記載してしまう場合があります。
お気づきの点がありましたら、お手数ですがご教示いただけると幸いです。
:::

**それでは、RSpecあるある今から言うよ〜🎶**

# まずなにしたらいいかわからない(思いつかない）
- よし、書くぞと思っても頭真っ白になりがち〜
もうなんにも出てこないんですね。テストってなんだっけ？となります。

  <dt>対策</dt>
  <dd>一旦落ち着いて、テスト内容を箇条書きで書き出してみる！</dd>
  <dd>例えば、こんな感じのユーザー登録のRSpecを書くぞとなったとき</dd>
[![Image from Gyazo](https://i.gyazo.com/294d6e787524cf607a2e00234b043221.png)](https://gyazo.com/294d6e787524cf607a2e00234b043221)
※Railsチュートリアルから引用

```
#　初めのホーム画面から
# Sing　upを押す
# Sing up画面へ遷移する
# Name　入れて
# Email　入れて
# Password　入れて
# Comfirmation 入れて
# Create my　account 押す
# 成功！ → Loginページにいる、成功しましたってメッセージ出る　
# 失敗したら？　　→ Sing upページにいる、失敗しましたってメッセージ出る
（入力フォームそれぞれの失敗パターンもありますが、割愛）
```
- 初めからコードで書こうとせず、実際に手動で確認する動作を文字に起こす。
- Rspecは、成功パターンと失敗パターンを書く。

ユーザー登録のテストは比較的簡単に書けそうです！
- 例えばこれが、ログインしたユーザーが投稿できるブログアプリのブログのテストを作るとなった時…
コード書いた後にテストを書く場合は`Controller`に記載した内容を見てみるとテストすべき内容のヒントが得られそうです！

```ruby
class ArticleController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy
# 事前にログインしておかないといけないな…
   ...

  def create
    @article = current_user.articles.new(article_params)
#   記事内容の入力(article_params)は　titelとcontentの２つの項目の入力だな…

    if @article.save
      redirect_to @article, notice: "記事を登録しました。"
#     内容が保存できたら、記事詳細に遷移、flashメッセージの表示がある…
    else
      flash.now[:danger] = "記事を登録できませんでした"
      render :new　
#     内容が保存できなかったら、新規作成に遷移、flashメッセージの表示がある…
    end
  end
  ...

  private

  def article_params
    params.require(:article).permit(:title, :content)
  end

  def set_article
    @article = current_user.articles.find(params[:id])
  end
end

```

# 書き方がわからない
- テスト内容はなんとなくわかったけど、これをどうやってコードにするんだ？
どこにどうやって書けばいいか、ここでも頭真っ白になりがち〜　ですね。

例えば先ほどのユーザー登録に関するテストを作る場合、


System specの最初の画面はこんな感じですね。
```ruby
require 'rails_helper'

RSpec.describe "Users", type: :system do

end
```
- `describe`, `context`, `it`
RSpecを勉強し始めたら、何となくこの３つを書くということが思いつきますが、どうやって分けて書いたらいいんだ？　となりました。

ざっくり役割を見るとこんな感じ！

<table>
  <thead>
    <tr>
      <th>名前</th> <th>役割</th>
    </tr>
  </thead>
  <tr>
    <td> describe </td> <td>テストの主題、テストの対象となる機能や処理</td>
  </tr>
  <tr>
    <td> contex </td> <td>条件や状況、状態</td>
  </tr>
  <tr>
    <td> it </td> <td>期待する動作、結果</td>
  </tr>
</table>

`describe`は、やさしく言い換えると「どこのテストをするの？」ということを書くといいでしょう。
例えば、ユーザーの新規登録であれば、以下のようにそのまま書けそうです。

```ruby
describe 'ユーザーの新規登録' do
```

`context`は、状況や条件なので、例えば、成功失敗パターンはここで分岐させて以下のように記載するようになります。

```ruby
context 'フォームを正しく入力できた場合' do
...

context 'フォームを正しく入力できなかった場合' do
...
```

`it`は、動いて欲しい結果を書きますので、最終的な動きを書いていきます。
```ruby
it '新規登録が成功する' do
...

it '新規登録が失敗する' do
...
```
この3つと、先ほど文字に起こした内容をCapybaraに書き直せば、system specっぽくなりそうです！

```ruby
require 'rails_helper'

RSpec.describe "Users", type: :system do
  describe 'ユーザー新規登録' do
   context 'フォームを正しく入力できた時' do
     it '新規登録が成功する' do
       visit root_path #　初めのホーム画面から
       click_button 'Sing up' # Sing　upを押す
       visit new_user_path # Sing up画面へ遷移する
       fill_in 'foo' # Name　入れて
       fill_in 'example@example.com' # Email　入れて
       fill_in 'password' # Password　入れて
       fill_in 'password' # Comfirmation 入れて
       click_button 'Create my account' # Create my　account 押す
       expect(page).to have_content '登録しました'
       expect(current_path).to eq login_path
       # 成功！ → Loginページにいる、成功しましたってメッセージ出る　
    end
  end

    context 'フォームを正しく入力できなかった時' do
      it '新規登録が失敗する' do
        ... # どこかの項目を空欄にするなどして記載する
        expect(page).to have_content '登録できませんでした'
        expect(current_path).to eq new_user_path
        # 失敗したら？　　→ Sing upページにいる、失敗しましたってメッセージ出る
      end
    end
  
```
良い感じにかけているのではないでしょうか？

慣れないうちはCapybaraの記述がパッと出てこないのでこちら伊藤淳一さんの
[使えるRSpec入門・その4「どんなブラウザ操作も自由自在！逆引きCapybara大辞典」](https://qiita.com/jnchito/items/607f956263c38a5fec24)
で探しながらコードに起こすといいかもしれません！


# 終わりに
- RSpecは、ひとつずつ分解して考えると難しくない！　こわくない！
- 冗長になってしまっても、細かくわかりやすい方がいいとされているので、どんどん書いていきましょう！
- 他にも、`factory_bot`や`let`などのつまづきポイントがありますが、また別の機会に書いてみようと思います！

# 参考にした記事
https://www.wantedly.com/users/97689516/post_articles/293185
https://qiita.com/jnchito/items/42193d066bd61c740612
https://qiita.com/jnchito/items/607f956263c38a5fec24
https://qiita.com/shin1rok/items/a2c0dd6c136c1b9a8803
https://qiita.com/hawkcookie/items/d7965be4adbeb2490229