時間をかけ調べました。
間違っている箇所があればご指摘お願いします。
自分がかけたバリデーションチェックのRSpecをコーディングを公開します。
views/devise/registrations/new.thml.erb
すべて必須なので全項目に---presence: true
のバリデーションがかかっています。
このテストコードを難しいと感じる点
Q1.生年月日欄 どのようにテストコードを書けば良いのか?
数字3つ用意して、「年」「月」「日」を間に挟むのか??? +とかでつなぐのか?
valid?というコードの目的を知るとわかる
Q2.最低字数6文字で英数混合のパスワードを作る
ググっても6文字で英数混合パスワードというものは出てこない。うーーっ
Fakerのパスワードで実現するのはムズカしいと知ることから始まる
Q3.エラーメッセージはどんなメッセージを書くのか?
これから作るアプリ完成時の表示を想像しないといけない。これまた難問。ググるか?
何に対してテストするかを考える。
テストの仕様
バリデーションチェック「正常系」
①全ての項目がきちんと条件通り揃ってusersテーブルに「保存」される
→全て必須なので1通りのみ
バリデーションチェック「異常系」
②1つの項目が欠けた場合を想定して、全ての項目で欠けたパターンのusersテーブルに「保存」されないチェック
→全ての項目なのでニックネーム・メールアドレス・パスワード・パスワード(確認)・お名前(姓)・お名前(名)・お名前(カナ・姓)・お名前(カナ・名)・生年月日の9通り
実装に向けての準備
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', '~> 4.0.0'
gem 'factory_bot_rails'
gem 'faker'
gem 'gimei'
end
RSpec:Ruby専用テスティングフレームワーク
faker:テスト用のダミーデータをランダムに生成するGem
gimei:日本語対応のテスト用のダミーデータをランダムに生成するGem
以上をインストールしました。
bundle install
次に
rails g rspec:install
さらに
fakerの作成ダミーデータの仕様決定のためのファイルを用意します。
specフォルダの下にfactoriesというフォルダと「テーブル名(複数形名)」.rbのフォルダを作って用意します。
ダミーデータの仕様を決める設計図
以下になります。
FactoryBot.define do
#1.ニックネーム
nickname {Faker::Name.last_name}
#2.メールアドレス
email {Faker::Internet.free_email}
#3.パスワード
password {Faker::Lorem.characters(number: 10, min_alpha: 4, min_numeric: 1) }
#4.確認用パスワード
password_confirmation {password}
#5.漢字(姓)
first_name { Gimei.first.kanji }
#6.漢字(名)
last_name { Gimei.last.kanji }
#7.漢字(姓・カナ)#pronoはpronounceでカナとしています。
first_name_prono { Gimei.first.katakana }
#8.漢字(名・カナ)#pronoはpronounceでカナとしています。
last_name_prono { Gimei.last.katakana }
#9.生年月日
birthday { Faker::Date.backward }
end
end
Gimei.first.kanjiはGimeiGemのおかげで漢字が入ります。
Gimei.last.kanjiも同様に漢字が入ります。
Gimei.first.katakanaはGimeiGemのおかげでカタカナが入ります。
Gimei.last.katakanaはGimeiGemのおかげでカタカナが入ります。
password {Faker::Lorem.characters(number: 10, min_alpha: 4, min_numeric: 1) }
については6文字で英数混合の設定にとても苦労したので、別で詳しく解説しています。よければリンク先でご確認いただければと思います。
Fakerを使って英数混合のパスワードを作る(Q2の解答にもなっております)
↓↓↓
はじめて書いたテストコード
require 'rails_helper'
RSpec.describe User, type: :model do
describe '#create' do
before do
#インスタンス変数で渡す:理由 describe,itの変数のスコープが違うので
#:userはハッシュのシンボルになっていてspec/factories/users.rbで作った設計図通りの
ランダムなダミーデータを作ってくれます。
@user = FactoryBot.build(:user)
end
#正常系
it 'nickame,email,password,password_confirmation,first_name,last_name,first_name_prono,last_name_prono,birthdayの値が存在すれば登録できること' do
expect(@user).to be_valid
end
#異常系1
it 'nicknameが空では登録できないこと' do
@user.nickname = ''
@user.valid?
expect(@user.errors.full_messages).to include("Nickname can't be blank")
end
#異常系2
it 'emailが空では登録できないこと' do
@user.email = ''
@user.valid?
expect(@user.errors.full_messages).to include("Email can't be blank")
end
#異常系3
it 'paswordが空では登録できないこと' do
@user.password = ''
@user.valid?
expect(@user.errors.full_messages).to include("Password can't be blank")
end
#異常系4
it 'pasword_confirmationが空では登録できないこと' do
@user.password_confirmation = ''
@user.valid?
expect(@user.errors.full_messages).to include("Password confirmation can't be blank")
end
#異常系5
it 'first_nameが空では登録できないこと' do
@user.first_name = ''
@user.valid?
expect(@user.errors.full_messages).to include("First name can't be blank")
end
#異常系6
it 'last_nameが空では登録できないこと' do
@user.last_name = ''
@user.valid?
expect(@user.errors.full_messages).to include("Last name can't be blank")
end
#異常系7
it 'first_name_pronoが空では登録できないこと' do
@user.first_name_prono = ''
@user.valid?
expect(@user.errors.full_messages).to include("First name prono can't be blank")
end
#異常系8
it 'last_name_pronoが空では登録できないこと' do
@user.last_name_prono = ''
@user.valid?
expect(@user.errors.full_messages).to include("Last name prono can't be blank")
end
#異常系9
it 'birthdayが空では登録できないこと' do
@user.birthday = ''
@user.valid?
expect(@user.errors.full_messages).to include("Birthday can't be blank")
end
end
end
参考
・valid?メソッドは以下の2つの役割
*Q3の「エラーメッセージはどんなメッセージを書くのか?」の解答にもなっています。
①true/falseを返す
true | false |
---|---|
作成したデータが正しく保存される場合 | 保存されない場合はfalse |
②保存されない場合は「なぜ保存されないのか」のエラーメッセージを生成する
Q3の解答
・バリデーション presence: trueは空欄では保存できない
・それに対応するエラーメッセージは「〜can't be blank」(=空欄で保存はできない)
参考:エラーメッセージ集
②の理由からincludeの後に表示されるメッセージを書くことになっています。テストを作った後にbinding.pryしてコンソールでどんなメッセージが表示されるのかを取得しておきました。ご参考まで。
取得コマンド |
---|
@user.errors.full_messages |
エラーメッセージはモデルのerrorsに格納されています。
*userモデルなので @userになっています。
[1] pry(#<RSpec::ExampleGroups::User::Nested>)> user.errors.full_messages
=> ["Email can't be blank",
"Email can't be blank",
"Password can't be blank",
"Nickname can't be blank",
"Encrypted password can't be blank",
"First name can't be blank",
"Last name can't be blank",
"First name prono can't be blank",
"Last name prono can't be blank"]
基本:userモデルバリデーションで「presence: ture」とした場合のエラーメッセージは
「〜can't be blank」が共通部分となります。
’保存先カラム名を元に、〜部分の主語を変え、先頭を大文字にし、スネークケースで命名されていれば_(アンダーバー)をはずして主語を書いてください。’
Q2の解答
姓年月日がどんなview画面で構成されているかはいっさい関係いなく
データベースに保存されるかされないかをテストしているので保存されているデータの形式を確認してテストコードを書けば良い。
データベースには以下のようにデータが保存されているので
fakerにFaker::Date.backward
こうすると
テストが成功すると「2019-01-03」のようなダミーデータを作ってくれます。
nickame,email,password,password_comfirmation,first_name,last_name,first_name_prono,
last_name_prono,birthdayの値が存在すれば登録できること
nicknameが空では登録できないこと
emailが空では登録できないこと
paswordが空では登録できないこと
pasword_confirmationが空では登録できないこと
first_nameが空では登録できないこと
last_nameが空では登録できないこと
first_name_pronoが空では登録できないこと
last_name_pronoが空では登録できないこと
birthdayが空では登録できないこと
ひとまず段落です。
参考
単体テストコードRspecでの.validか.valid?か(初期の私の記事です。よかったら)