RSPECテスト 単体テスト
今回はMVCのモデルのテストを書いていきます。
おすすめのGemなども記載しているので参考にしてみて下さい。
1:Rspecファイルの作成
Gemfileに記載 bundle install
group :development, :test do
gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"
gem "brakeman", require: false
gem "rubocop-rails-omakase", require: false
gem "rspec-rails" #これ!!!!
end
group :development do
gem "web-console"
end
group :test do
gem "capybara"
gem "selenium-webdriver"
gem "simplecov", require: false # 面白いGemも入れました
end
2:テスト用DBの作成
# 先にマイグレーションをしてスキーマを最新状態にする
$ docker compose exec web bundle exec rails db:migrate
$ docker compose exec web bundle exec rails db:test:prepare
※一応DBが存在するか確認
# テスト用データベースへアクセスします
$ docker compose exec web bundle exec rails dbconsole -e test
# postgre sqlはこのコマンドを打つ
$ app_development-# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+----------
public | ar_internal_metadata | table | postgres
public | books | table | postgres
public | schema_migrations | table | postgres
(3 rows)
しっかり入ってます
それぞれの意味
3つのテーブル
books
アプリで使っているBooksテーブル
db:test:prepare でスキーマが反映されているschema_migrations
どのマイグレーションが実行済みか記録するRails管理用のテーブルar_internal_metadata
今どの環境(development/test/production)かをRailsが管理するためのテーブル
3:モデルテストの導入
# bookモデルのテストを導入
$ docker compose exec web bundle exec rails generate rspec:model Book
require 'rails_helper'
RSpec.describe Book, type: :model do
# テスト用のセットアップをここに書く
let(:valid_attributes) do
{
name: "テスト本",
author: "テスト著者",
publisher: "テスト出版社",
description: "テスト概要",
book_url: "https://example.com",
horror_level: 1,
mystery_level: 1
}
end
# ─── バリデーション ───────────────────────────────────────
describe "バリデーション" do
context "有効なデータの場合" do
it "全項目が揃っていれば有効" do
book = Book.new(valid_attributes)
expect(book).to be_valid
end
end
context "name のバリデーション" do
it "name が空だと無効" do
book = Book.new(valid_attributes.merge(name: ""))
expect(book).not_to be_valid
end
it "name が50文字以内なら有効" do
book = Book.new(valid_attributes.merge(name: "あ" * 50))
expect(book).to be_valid
end
it "name が51文字以上だと無効" do
book = Book.new(valid_attributes.merge(name: "あ" * 51))
expect(book).not_to be_valid
end
it "name が重複していると無効" do
Book.create!(valid_attributes)
book = Book.new(valid_attributes)
expect(book).not_to be_valid
end
end
context "author のバリデーション" do
it "author が空だと無効" do
book = Book.new(valid_attributes.merge(author: ""))
expect(book).not_to be_valid
end
it "author が20文字以内なら有効" do
book = Book.new(valid_attributes.merge(author: "あ" * 20))
expect(book).to be_valid
end
it "author が21文字以上だと無効" do
book = Book.new(valid_attributes.merge(author: "あ" * 21))
expect(book).not_to be_valid
end
end
context "publisher のバリデーション" do
it "publisher が空だと無効" do
book = Book.new(valid_attributes.merge(publisher: ""))
expect(book).not_to be_valid
end
it "publisher が20文字以内なら有効" do
book = Book.new(valid_attributes.merge(publisher: "あ" * 20))
expect(book).to be_valid
end
it "publisher が21文字以上だと無効" do
book = Book.new(valid_attributes.merge(publisher: "あ" * 21))
expect(book).not_to be_valid
end
end
context "description のバリデーション" do
it "description が空だと無効" do
book = Book.new(valid_attributes.merge(description: ""))
expect(book).not_to be_valid
end
it "description が255文字以内なら有効" do
book = Book.new(valid_attributes.merge(description: "あ" * 255))
expect(book).to be_valid
end
it "description が256文字以上だと無効" do
book = Book.new(valid_attributes.merge(description: "あ" * 256))
expect(book).not_to be_valid
end
end
context "book_url のバリデーション" do
it "book_url が空だと無効" do
book = Book.new(valid_attributes.merge(book_url: ""))
expect(book).not_to be_valid
end
end
context "horror_level のバリデーション" do
it "horror_level が0なら有効" do
book = Book.new(valid_attributes.merge(horror_level: 0))
expect(book).to be_valid
end
it "horror_level が2なら有効" do
book = Book.new(valid_attributes.merge(horror_level: 2))
expect(book).to be_valid
end
it "horror_level が3だと無効" do
book = Book.new(valid_attributes.merge(horror_level: 3))
expect(book).not_to be_valid
end
end
context "mystery_level のバリデーション" do
it "mystery_level が0なら有効" do
book = Book.new(valid_attributes.merge(mystery_level: 0))
expect(book).to be_valid
end
it "mystery_level が2なら有効" do
book = Book.new(valid_attributes.merge(mystery_level: 2))
expect(book).to be_valid
end
it "mystery_level が3だと無効" do
book = Book.new(valid_attributes.merge(mystery_level: 3))
expect(book).not_to be_valid
end
end
end
本の登録関係のテストを記入
bookモデル
4:おもしろ機能 カバレッジ率測るgem
spec/rails_helper.rbの上の方に
require 'simplecov' # ← 追加
SimpleCov.start 'rails' # ← 追加
その後
$ docker compose exec web bundle exec rspec spec/models/book_spec.rb
Finished in 0.56226 seconds (files took 6.68 seconds to load)
23 examples, 0 failures
Coverage report generated for RSpec to /rails/coverage.
Line Coverage: 12.33% (18 / 146)
# ここでカバレッジ率がわかる 12.33%
# カバレッジ率がまるわかりのサイトに飛ぶ
$ open coverage/index.html
こんな感じです。
この結果を見ながらどんどんテスト書いていきたいと思います。
関連記事

