目的
Railsで作成したアプリにテストコードを実装する。
開発環境
macOS: Big Sur
Rubyバージョン: 2.6.5
Railsバージョン: 6.0.0
前提
- アプリを作成済み。【Rails】簡単な投稿アプリの作成
-
devise
を導入済み。【Rails】ユーザー管理機能(devise)の導入 - アプリを日本語化対応済み。【Rails】Railsの日本語化
-
FactoryBot
及びFaker
を導入済み。FactoryBot・Fakerの導入
手順
はじめに
今回は単体テストコードの実装を行っていきます。
テストコードを記述するメリットとして以下のようなメリットが考えられます。
- 人為的ミスのリスク回避。
- 作業効率化。
- どのように確かめたか記録を残す。
また、テストコードは正常系
と異常系
に分けられ、
正常系は「ユーザーが開発者の意図する操作を行った時の挙動」
を確認するテストコード、
異常系は「ユーザーが開発者の意図しない操作を行った時の挙動」
を確認するテストコードと分類されます。
RSpecの導入
それでは早速始めていきます!
まず、Railsのテストコードを書くためにRSpec
というGemをインストールします。
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'
end
この時、group :development, :test
というグループの中に記述しまします。
そうすることで、Gemの動作に制限をもたせます。
% bundle install
これでインストールできました!
RSpecの設定
次にアプリ内で使用するための設定をしていきます。
rails g rspec:install
インストールが完了すると、ディレクトリやファイルが生成されます。
続いて生成された.rspec
ファイルを開き、テストコードの結果をターミナル上に可視化するため、以下のように記述します。
--format documentation
これでRSpecの設定は完了です!
ファイルの用意
テストコードを記述するファイルを用意します。
今回はUserモデルのテストコードを実装するため、下記コマンドにてテストファイルを生成しましょう!
% rails g rspec:model user
これで、事前準備は完了です!
モデル単体テストの実装
次にテストコードを実装していきます!
require 'rails_helper'
RSpec.describe User, type: :model do
describe '#create' do
before do
@user = FactoryBot.build(:user)
end
context '登録ができる時' do
it '全ての項目の入力がが存在すれば登録できること' do
expect(@user).to be_valid
end
it 'passwordが6文字以上かつ半角英数字混合であれば登録できること' do
@user.password = '12345a'
@user.password_confirmation = '12345a'
expect(@user).to be_valid
end
end
context '登録ができない時' do
it 'nicknameが空では登録できないこと' do
@user.nickname = ''
@user.valid?
expect(@user.errors.full_messages).to include("ニックネームを入力してください")
end
it 'emailが空では登録できないこと' do
@user.email = ''
@user.valid?
expect(@user.errors.full_messages).to include("メールアドレスが入力されていません。")
end
it '重複したemailが存在する場合登録できないこと' do
@user.save
another_user = FactoryBot.build(:user, email: @user.email)
another_user.valid?
expect(another_user.errors.full_messages).to include("メールアドレスは既に使用されています。")
end
it 'passwordが空では登録できないこと' do
@user.password = ''
@user.valid?
expect(@user.errors.full_messages).to include("パスワードが入力されていません。", "もう一度パスワードを入力してくださいとパスワードの入力が一致しません")
end
it 'passwordが5文字以下であれば登録できないこと' do
@user.password = '1234a'
@user.password_confirmation = '1234a'
@user.valid?
expect(@user.errors.full_messages).to include("パスワードは6文字以上に設定して下さい。")
end
it 'passwordが半角数字のみのときに登録できないこと' do
@user.password = '123456'
@user.password_confirmation = '123456'
@user.valid?
expect(@user.errors.full_messages).to include("パスワードは有効でありません。")
end
it 'passwordが半角英語のみのときに登録できないこと' do
@user.password = 'abcdef'
@user.password_confirmation = 'abcdef'
@user.valid?
expect(@user.errors.full_messages).to include("パスワードは有効でありません。")
end
it 'passwordが全角のときに登録できないこと' do
@user.password = '12345A'
@user.password_confirmation = '12345A'
@user.valid?
expect(@user.errors.full_messages).to include("パスワードは有効でありません。")
end
it 'passwordとpassword_confirmationが不一致では登録できないこと' do
@user.password = '12345a'
@user.password_confirmation = '123456a'
@user.valid?
expect(@user.errors.full_messages).to include("もう一度パスワードを入力してくださいとパスワードの入力が一致しません")
end
end
end
end
それでは順番に説明していきます!
describe '#create' do
このdescribeメソッド
は、テストコードのグループ分けを行っています。
どの機能に対してのテストを行うか
をdescribeでグループ分けし、その中に各テストコードを記述します。
テストコードが膨大になると解読が大変になるので、付けておきます!
#describe '#create' do
it 'nicknameが空では登録できないこと' do
次にこのitメソッド
ですが、describeメソッド同様に、グループ分けを行っています。
itの場合はより詳細に、describeメソッドに記述した機能において、どのような状況のテストを行うか
を明記します。
@user.valid?
valid?は、バリデーションを実行させて、エラーがあるかどうかを判断するメソッドです。
エラーがない場合はtrueを、ある場合はfalseを返します。
また、エラーがあると判断された場合は、エラーの内容を示すエラーメッセージを生成します。
テストコードの実行
テストコードが記述できたらテストの実行をします。
% bundle exec rspec spec/models/user_spec.rb
bundle exec
でGemの依存関係を整理しています。
テストを実行し、下記画像のように成功すれば実装完了です!
最後に
以上で単体テストコードの実装は完了です。
では。