0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

テストコードを書く

Posted at

なぜテストコードを書くのか

アプリケーションが、想定通り正しく動くのか、確認するため。

Ruby on Railsでは、アプリケーションのテストコードを記述する機能を、RSpecというGemを使うことで便利に実装できる。

  1. RSpecを導入する

① まず、RSpecのGemを導入する

Gemfile

group :development, :test do
    (  ~省略~ )
  gem 'rspec-rails', '~> 4.0.0'
end

Gemfileを変更したので、

~ frima-app % bundle install

② RSpecをアプリ内にインストールする

~ frima-app % rails g rspec:install

③ .rspecファイルに、記述する
テストコードの結果を、ターミナル上で表示するため。

.rspec
( ~省略~ )
--format documentation
  1. FactoryBotを導入する

FactoryBot: 
インスタンスをまとめられるGem。 テストのときに毎回記述していた、ユーザー生成の記述などを、他のファイルに一まとめにして、各テストで用いるときに使う。

①Gemfile

group :development, :test do
  ( ~省略~ )
  gem 'factory_bot_rails'
end
% bundle install

②テストコードと、FactoryBotの記述をするファイルを、同時に作る

% rails g rspec:model user

③ FactoryBotで、インスタンスを一まとめに

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {'furima'}
    email                 {'furima@example'}
    password              {'123456'}
    password_confirmation {password}
  end
end

④ FactoryBotの使い方

spec/models/user_spec.rb
RSpec.describe User, type: :model do
 describe 'ユーザー新規登録' do
   before do
      @user = FactoryBot.build(:user) # Userのインスタンス生成
   end

   context '新規登録できないとき’
    it 'emailが同じだと登録できない' do
      @user.save
      another_user =FactoryBot.build(:user)  
      another_user.email = @user.email
      another_user.valid?
      expect(another_user.errors.full_messages).to include("Email has already been taken")
    end
      end
  end
  1. ランダムな値を生成するFakerを導入する

④のエラー文のように、アプリ内で重複したemailを使えないようにする場合、Fakerを使ったほうが良い。なぜなら、複数のテストを行う際に、FactoryBotで固定のemailで複数回試すため、「すでにemailの重複したインスタンスが存在する」といったような形でエラーが出るかもしれないから。

Gemfile

group :development, :test do
  ( ~省略~ )
  gem 'faker'
end
% bundle install

そして、2-③をFakerを使って表してみると、、、

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {'furima'}
    email                 {Faker::Internet.free_email}
    password              {Faker::Internet.password(min_length: 6)}
    password_confirmation {password}
  end
end
  1. テストコードを実行する
% bundle exec rspec spec/models/user_spec.rb 

5. 完成版

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {'furima'}
    email                 {Faker::Internet.free_email}
    password              {Faker::Internet.password(min_length: 6)}
    password_confirmation {password}
  end
end
spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'ユーザー新規登録' do
    before do
      @user = FactoryBot.build(:user)
    end

    context '新規登録できる時' do
      it '全ての値が正しく入力されていれば保存できる' do
        expect(@user).to be_valid
      end
      it 'emailが@を含めば登録できる' do
        @user.email= 'test@test.com'
        expect(@user).to be_valid
      end
      it 'nicknameが10文字以下なら登録できる' do
        @user.nickname='testtestte'
        expect(@user).to be_valid
      end
      it 'passwordとpassword_confirmationが6文字以上であれば登録できる' do
        @user.password='123456'
        @user.password_confirmation='123456'
        expect(@user).to be_valid
      end
      it 'passwordとpassword_confirmationが6文字以上であれば登録できる' do
        @user.password='123456'
        @user.password_confirmation='123456'
        expect(@user).to be_valid
      end
    end


    context '新規登録できない時' do
      it 'nicknameが空では登録できない' do
        @user.nickname=''
        @user.valid?
        expect(@user.errors.full_messages).to include("Nickname can't be blank")
      end
      it 'emailが空では登録できない' do
        @user.email=''
        @user.valid?
        expect(@user.errors.full_messages).to include("Email can't be blank")
      end
      it 'emailが全角では登録できない' do
        @user.email='123@123'
        @user.valid?
        expect(@user.errors.full_messages).to include("Email is invalid")
      end
      it 'emailが同じだと登録できない' do
        @user.save
        another_user = FactoryBot.build(:user)
        another_user.email=@user.email
        another_user.valid?
        expect(another_user.errors.full_messages).to include("Email has already been taken")
      end
      it 'emailが@を含まないと登録できない' do
        @user.email='testtest.com'
        @user.valid?
        expect(@user.errors.full_messages).to include("Email is invalid")
      end
      it 'passwordが空では登録できない' do
        @user.password=''
        @user.valid?
        expect(@user.errors.full_messages).to include("Password can't be blank")
      end
      it 'passwordが5文字以下だと登録できない' do
        @user.password='12345'
        @user.valid?
        expect(@user.errors.full_messages).to include("Password is too short (minimum is 6 characters)")
      end

      it 'passwordとpassword_confirmationが不一致だと登録できない' do
        @user.password='123456'
        @user.password_confirmation='234567'
        @user.valid?
        expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password")
      end
      
    end
  end
end
0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?