学習の書き留め プログラミング勉強中

プログラミングで学んだことを日記として残して行こうと思います

今日の学習

今日学んだこと 2021/01/02

学習項目

単体テストコードの概要(RSpec

学習内容

RSpecを使ったテスト

RSpecの導入方法

①Gemfileに記述

# group :development, :test のグループ内に記述
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' # RSpecの導入
  gem 'factory_bot_rails' # テストで使うインスタンスをまとめてくれるGem
  gem 'faker' # ランダムな値を生成するGem
end
# 省略

②bundle install 実行

RSpecのインストール

rails g rspec:install

④テストコードの結果をターミナル上に可視化するための設定をする

# .rspec
--require spec_helper
--format documentation

モデルの単体テスト方法

①テストファイルの作成

rails g rspec:model モデル名

②テストで使うインスタンスの生成

# spec/factories/モデル名.rb
FactoryBot.define do
  factory :モデル名 do
    name         {Faker::Name.initials(number: 文字数)}
    email         {Faker::Internet.free_email}
    password  {Faker::Internet.password(min_length: 文字数)}

③テストコードの記述

#spec/models/モデル名_spec.rb
require 'rails_helper'
RSpec.describe モデル名, type: :model do
  before do
    @インスタンス名 = FactoryBot.build(:モデル名)
  end

  describe 'ユーザー新規登録' do
    it "nameが空だと登録できない" do
      @インスタンス名.name = ""
      @インスタンス名.valid?
      expect(@インスタンス名.errors.full_messages).to include ("name can't be blank")
    end
  end
end

まず before do ... end の間の記述は②で書いたインスタンスを生成する。
describe はどの機能に対してテストを行うのグループ分けをし、
細分化、特定の条件を指定してグループ分けをする場合、入子構造にしてcontextのなかに、条件を記載する。
入子構造の it でどのような状況のテストをするのか明記する。itで分けたグループのことを example と呼ぶ。 今回はnameが空の状態だと登録できないのかを検証するために、
@インスタンス名.name = "" でnameを空に上書きする。
その後に @インスタンス名.valid? でバリテーションを実行してエラーがあるかどうかを検証する。
最後に @インスタンス名.errors.full_messages で実際のエラーメッセージを出し、その中に、nameが空の時に出るエラーメッセージ "name can't be blank" が含まれているか include を使って検証する。(同一かどうかを検証する場合は eq )

まとめるとこの処理はnameが空の状態でバリテーションを実行した際に出てくるエラーメッセージが、nameが空の時にでてくるエラーメセージと同一のものか? と言う内容を検証していることになる。

④テストコードの実行

bundle exec rspec spec/models/モデル名_spec.rb

コントローラーの単体テスト方法

①テストファイルの作成

rails g rspec:request コントローラー名

②テストコードの記述

#spec/models/モデル名_spec.rb
require 'rails_helper'
RSpec.describe コントローラー名Controller, type: :request do
  before do
    @インスタンス名 = FactoryBot.create(:コントローラー名)
  end

  describe "GET #index" do
    it "indexアクションにリクエストすると正常にレスポンスが返ってくる" do 
      get root_path
      expect(response.status).to eq 200
end
    it "indexアクションにリクエストするとレスポンスに投稿済みのツイートのテキストが存在する" do 
      get root_path
      expect(response.body).to include @インスタンス名.text
    end
  end
end

まず、今回はツイートなどが存在するかを調べるため create で情報をデータベースに保存する。(テストようのためテストのたびに消去される)
HTTPメソッドを使って、リクエストを送る。 responce でそのリクエストに対して、のレスポンスを受け取る。HTTPステータスコードだと、200が処理の成功のため responce.status が 200 と同一かと言う検証を行う。
もう一点のは response.body でHTMLの情報を取得し、テストに期待する情報が含まれているかと言う検証を行う。

④テストコードの実行

bundle exec rspec spec/models/コントローラー名_spec.rb

以上があらかたのテスト方法になる。

まとめ

地味だけど大切。