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?

【Rails】単体テストを実際に書いてみました -Model編-

0
Posted at

RSPECテスト 単体テスト 

テストと言ってもいろいろある
Image from Gyazo

今回は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

Image from Gyazo

こんな感じです。
この結果を見ながらどんどんテスト書いていきたいと思います。

関連記事

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?