6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2021年10月1日 現場Rails Chapter5-8 タスクの一覧表示機能のSystem Spec

タスクの一覧表示機能のSystem Spec

タスク一覧表示機能をテストする場合、以下のようなSystem Specを書きます。

ここではファクトリーに定義したテストユーザーをそのまま使わずに、"ユーザーA"を定義しています。今後、ユーザーBなど別のユーザーを扱う際にスムーズにするためです。

require 'rails_helper'

describe 'タスク管理機能', type: :system do
  describe '一覧表示機能' do
    before do
      # ユーザーAを作成
      # 作成者がユーザーAであるタスクを作成しておく
      user_a = FactoryBot.create(:user, name: 'ユーザーA', email: 'a@example.com')
      FactoryBot.create(:task, name: '最初のタスク', user: user_a)
    end
    context 'ユーザーAがログインしているとき' do
      before do
        # ユーザーAでログインする
      end
      
      it 'ユーザーAが作成したタスクが表示される' do
        # 作成済のタスクの名称が画面上に表示されていることを確認
      end
    end
  end
end

FactoryBotを用いてデータを作る

FactoryBotを用いてデータを作る場合、buildまたはcreateというメソッドを使います。

before do
  # テストユーザーを作成(今回の場合は、user_aを作成)
  user_a = FactoryBot.create(:user, name: 'ユーザーA', email: 'a@example.com')

  # 作成者がユーザーAであるタスクを作成しておく
  # userオプションを付けることで、taskファクトリーとuserの関連を指定している。=>user_aが作成したタスクになる
  FactoryBot.create(:task, :name: '最初のタスク', user: user_a)
end

今回のようにユーザーAという特定のユーザーを作りたいので、nameカラムやemailカラムを直接指定して変更しました。もしオプションを指定しない場合、FactoryBotの定義内で、設定された値でデータが作成されます。

# FactoryBotの定義
FactoryBot.define do
  factory :user do
    name { 'テストユーザ' }
    email { 'test1@example.com' }
    password { 'password' }
  end
end

また、タスクデータを作る際に、userオプションを指定しない場合は、新しいuserオブジェクトを合わせて作成します。つまり、毎回タスクオプジェクトを作る際に新たなuserオブジェクトも作成されます。

createとbuildの挙動の違い

createはオブジェクトを作成してデータベースに登録します。
buildはオブジェクトを作成するだけでデータベースに登録しません。
また、RSpecでのcreateはテスト終了時にDBが自動でロールバックされます。
これによりテストの度にFactoryBot.createを実行されても、また新たなデータとしてデータベースに登録できます。(ロールバックが行われないとDBエラーになります。)

createとbuildの使用用途の違い

DBの値を利用するテストが必要な場合にcreateを使います。
データの個数計算や一意のデータしか保存できないことなど、DBにアクセスして確認するテストにはcraeteを利用します。
DBにアクセスする必要がないテストの場合は、テストの実行速度を上げるためにbuildを利用します。

before(前提処理)にユーザーAとしてログインする処理を記載する

before do
  # ログインパスで、ログイン画面にアクセスする
  visit login_path
  # メールアドレスというラベル要素に入力値を入力する
  fill_in 'メールアドレス', with: 'a@example.com'
  # パスワードというラベル要素に入力値を入力する
  fill_in 'パスワード', with: 'password'
  # ログインボタンを押す
  click_button 'ログインする'
ene

visit

特定のURLでアクセスする操作です。visit[URL] で実現できます。今回のログイン画面へのアクセスではこのように書きます。

visit login_path  

fill_in

ラベルのついたテキストフィールドに値を入力する際に使用します。ラベルと入力値を指定して記述します。以下、メールアドレスでの例です。

fill_in 'メールアドレス', with: 'a@example.com'

click_button

ラベルのあるボタンを押します。以下、ログインボタンでの例です。

click_button 'ログイン'

it内の処理を記述する

it 'ユーザーAが作成したタスクが表示される' do
  # page(画面)に「最初のタスク」という内容があることを期待する
  # ここで、期待した処理がある時に、trueが返る
  expect(page).to have_content '最初のタスク'
end

今までで説明したコードを応用すると、タスク一覧表示機能のSystem Specは以下のようになります。

require 'rails_helper'

describe 'タスク管理機能', type: :system do
  describe '一覧表示機能' do
    before do
      user_a = FactoryBot.create(:user, name: 'ユーザーA', email: 'a@example.com')
      FactoryBot.create(:task, name: '最初のタスク', user: user_a)
    end
    
    context 'ユーザーAがログインしているとき' do
      before do
        visit login_path
        fill_in 'メールアドレス', with: 'a@example.com'
        fill_in 'パスワード', with: 'password'
        click_button 'ログインする'
      end
      
      it 'ユーザーAが作成したタスクが表示される' do
        expect(page).to have_content '最初のタスク'
      end
    end
  end
end

これでtasks_spec.rbのテストコードはひとまず完成しました。 以下のコマンドを実行することでテストが実行出来ます。

$ bundle exec rspec spec/system/tasks_spec.rb
$ bin/rspec 〜ようにbinでも実行可能です。

RSpecでの文法の捉え方

expect ~ to -


「~に-を期待する」 「I expect that ~.」を言い換えた「~に-」を期待するという場合に使います。

最後に...

今回のテストコードは書籍の序盤の内容に沿って書いたテストのため、まだまだ修正出来る点があるかと思います。 良ければ次回以降の記事も参考にしてください。

参照

本書のみ