LoginSignup
51
47

More than 5 years have passed since last update.

[Rails][RSpec] Capybaraでフォーム入力をシミュレートしてテストする

Last updated at Posted at 2013-12-03

Ruby on Rails Tutorialのエッセンスを自分なりに整理してみる10

[Rails4.0] フォームの基本とStrongParametersを理解する
http://qiita.com/kidachi_/items/7c1a9b61dd1853d5a7dc
の続き。

Ruby on Rails Tutorial(chapter7)
http://railstutorial.jp/chapters/sign-up?version=4.0#code-after_save_tests

概要

ユーザ登録等、よくあるフォーム入力を実装した時、
いちいちブラウザから様々なパターンの値を入力してテストするのは大変。
Capybaraのシミュレート機能を使って解決する。

今回用いるCapybaraのメソッド

以下の2つ。

  • fill_in
  • change

fill_in

フォームへの入力をシミュレートする。

例えば、

fill_in "Name", with: "Example User"

これでフィールド名"Name"のinput属性に"Example User"の入力をシミュレートしたことになる。

より具体的に、以下のようなユーザ情報入力フォームがあるとする。

erb
    <%= form_for(@user) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation %>
      <%= f.submit "Create my account" , class: "btn btn-large btn-primary" %>

    <% end %>

この場合、以下のテストコードで各フィールドに対する値の入力が実現できる。

visit signup_path
fill_in "Name",         with: "Example User"
fill_in "Email",        with: "user@example.com"
fill_in "Password",     with: "foobar"
fill_in "Confirmation", with: "foobar"

change

オブジェクトとそのオブジェクトが持つメソッドを指定し、
その実行によって起きる変化を観測する。

click_buttonの後、User.countが1だけ変化する事を期待する例

expect do
  click_button "Create my account"
end.to change(User, :count).by(1)
  • オブジェクト(User)とシンボル(:count)を引数に取り、シンボルに該当する名前のメソッドを呼び出す。
  • expect do~end.toの後ろについて、ブロック内が実行される前後での変化を比較する。

実際のテストコード

上記2つのメソッドを用いて、

  • ユーザ登録ページ(signup)に訪れ
  • フォームに何らかの値を入力し(もしくは入力しないで)、
  • "Create my account"ボタンを押下

したケースをシミュレートするテストコード

require 'spec_helper'

describe "User pages" do

  subject { page }

  describe "signup" do

    before { visit signup_path }

    let(:submit) { "Create my account" }

    # 不正な値が入力された(正確には、何も入力されていない)ケース
    describe "with invalid information" do
      it "should not create a user" do
        #click_buttonの後、User.countが変化しない事を期待
        expect { click_button submit }.not_to change(User, :count)
      end
    end

    # 正しい値が入力されたケース
    describe "with valid information" do
      before do
        fill_in "Name",         with: "Example User"
        fill_in "Email",        with: "user@example.com"
        fill_in "Password",     with: "foobar"
        fill_in "Confirmation", with: "foobar"
      end
      it "should create a user" do
        #click_buttonの後、User.countが1だけ変化する事を期待
        expect { click_button submit }.to change(User, :count).by(1)
      end
    end
  end
end

便利!

関連

RSpecの基本等については以下も参照ください。

[Rails] RSpecによるBDD(振舞駆動開発)の基本 [SporkとGuardも]
http://qiita.com/kidachi_/items/cb8910eb74e924456df9

[Rails] RSpecのリファクタリング
http://qiita.com/kidachi_/items/ec184deb106e4e5c90c3

51
47
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
47