はじめに
単体テストコードを実行する流れをまとめる
単体テストコード実行流れ
1.テストコードを記載するファイルを作成する。
% rails g rspec:model user
(Userモデル用のテストファイルを作成できる。)
「create spec/models/user_spec.rb」と記載が出れば問題ない。
<補足>
RSpecでモデル、ビュー、コントローラーのテストを行うためには、rails_helper.rbというファイルを読み込む必要があるため、
上記で作成したテストファイルの1行目にはrequire 'rails_helper'と記述されている。
2.テストコードを記載
#userモデルの単体テストコードの一例(spec/models/user_spec.rb内)
require 'rails_helper'
RSpec.describe User, type: :model do
before do
@user = FactoryBot.build(:user)
end
describe 'ユーザー新規登録' do
context '新規登録できる場合' do
it '必要事項を全て過不足なく入力すると登録できる' do
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.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 = 'testmail'
@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が6文字未満では登録できない' do
@user.password = '00000'
@user.password_confirmation = '00000'
@user.valid?
expect(@user.errors.full_messages).to include('Password is too short (minimum is 6 characters)')
end
it 'passwordで半角英字のみでは登録できない' do
@user.password = 'aaaaaa'
@user.password_confirmation = 'aaaaaa'
@user.valid?
expect(@user.errors.full_messages).to include('Password には英字と数字の両方を含めて設定してください')
end
it 'passwordで半角数字のみでは登録できない' do
@user.password = '000000'
@user.password_confirmation = '000000'
@user.valid?
expect(@user.errors.full_messages).to include('Password には英字と数字の両方を含めて設定してください')
end
it '全角文字を含むパスワードでは登録できない' do
@user.password = 'aaa 111'
@user.password_confirmation = 'aaa 111'
@user.valid?
expect(@user.errors.full_messages).to include('Password には英字と数字の両方を含めて設定してください')
end
it 'passwordとpassword_confirmationが一致しないと登録できない' do
@user.password = 'aaa111'
@user.password_confirmation = 'bbb111'
@user.valid?
expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password")
end
it 'お名前(全角)は、名字が空では登録できない' do
@user.lastname = ''
@user.valid?
expect(@user.errors.full_messages).to include("Lastname can't be blank")
end
it 'お名前(全角)は、名前が空では登録できない' do
@user.firstname = ''
@user.valid?
expect(@user.errors.full_messages).to include("Firstname can't be blank")
end
it 'お名前(全角)は、名字を全角(漢字・ひらがな・カタカナ)で入力しないと登録できない' do
@user.lastname = 'ヤマダ'
@user.valid?
expect(@user.errors.full_messages).to include('Lastname 全角文字を使用してください')
end
it 'お名前(全角)は、名前を全角(漢字・ひらがな・カタカナ)で入力しないと登録できない' do
@user.firstname = 'タロウ'
@user.valid?
expect(@user.errors.full_messages).to include('Firstname 全角文字を使用してください')
end
it 'お名前カナ(全角)は、名字が空では登録できない' do
@user.lastname_kana = ''
@user.valid?
expect(@user.errors.full_messages).to include("Lastname kana can't be blank")
end
it 'お名前カナ(全角)は、名前が空では登録できない' do
@user.firstname_kana = ''
@user.valid?
expect(@user.errors.full_messages).to include("Firstname kana can't be blank")
end
it 'お名前カナ(全角)は、名字を全角(カタカナ)で入力しないと登録できない' do
@user.lastname_kana = 'ヤマダ'
@user.valid?
expect(@user.errors.full_messages).to include('Lastname kana 全角カタカナのみで入力して下さい')
end
it 'お名前カナ(全角)は、名前を全角(カタカナ)で入力しないと登録できない' do
@user.firstname_kana = 'タロウ'
@user.valid?
expect(@user.errors.full_messages).to include('Firstname kana 全角カタカナのみで入力して下さい')
end
it '生年月日が空だと登録できない' do
@user.birthday = ''
@user.valid?
expect(@user.errors.full_messages).to include("Birthday can't be blank")
end
end
end
end
<補足>
- be_valid
valid?メソッドでtrueが帰ってくることを期待する - valid?メソッド
バリデーションのテストを行い、登録可能なときは"true",登録不可の場合は"false"を返す - errors.full_messagesメソッド
valid?メソッドの返り値が"false"の時に、エラー文をできる - expect(A).to include(B)
Aの中に、Bが含まれることを期待する構文。(完全一致の場合は、マッチャである「include」→「eq」に変更)
詳細は、別途検索してみよう。
3.単体テストコードを記述する上での注意点
3-1.テストで使用するuser情報等の登録内容は、FactoryBotやFakerを使ってランダムに作成する。
# Gemfile内に下記2行を追記(FactoryBotやFaker)追加のため。
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails'
gem 'factory_bot_rails' ⇦ この行を追記する
gem 'faker' ⇦ この行を追記する
end
# Gemをアプリに導入
% bundle install
「spec」ディレクトリの中に「factories」ディレクトリを作成し、
FactoryBot用のusers.rbのファイルを作成する。
#作成したusers.rb内に下記のように記載する
FactoryBot.define do
factory :user do
nickname { Faker::Name.initials }
email { Faker::Internet.free_email }
password { 'a1' + Faker::Internet.password(min_length: 4, mix_case: false) }
password_confirmation { password }
lastname { 'やマ田' }
firstname { '太ろウ' }
lastname_kana { 'ヤマダ' }
firstname_kana { 'タロウ' }
birthday { Faker::Date.between(from: '1930-01-01', to: '2017-12-31') }
end
end
#FactoryBotの:userを呼び出すためには、spec/models/user_spec.rb内にbeforeとbuildメソッドを用いて下記のように記述する。
RSpec.describe User, type: :model do
before do
@user = FactoryBot.build(:user)
end
・・・中略
end
<注意点>
ターミナル上でrails cを用いて仮テストする際に、FactoryBotで値を作成できない(KeyErrorが出る)場合は、
% spring stop
(springというGemをストップさせるコマンド)
を実行してみると解決するかも。
3-2.可読性を上げることを意識する
describe do〜endやcontext do〜end、it do〜endを駆使し、他者が見やすいコードを記載するように意識する。
4.テストコードの実行
# userモデルのテストコード実行コマンド
% bundle exec rspec spec/models/user_spec.rb