[RUBY] [Ralis] About unit tests

At first

I will keep a memorandum of the procedure when unit testing the validation of the model using Rspc.

What is Rspec

A typical test tool for Ruby and Rails, a gem for testing by class or method.

environment

・ Rails 5.0.7.2 ・ Ruby 2.5.1 ・ Rspec-rails 3.9.0 ・ Factory_bot_rails 5.1.1

Advance preparation

1. Introduction of rspec and Factory_bot gem

gemfile

group :development, :test test do
# I want to use it in the development environment and the test environment, so I describe it in this.
gem 'rspec_rails'
gem 'factory_bot_gem' 

end

If you can write gem, bundle install

2. Create rspec file and check operation

At the terminal

$ rails g rspec:install

If the file is created as shown below after executing the command, it is ok.

create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

Now that the file has been created, in the terminal,

--require spec_helper
--format documentation

Add these two statements to the .spec file and execute the rspec execution command in the terminal to check the operation.

$ bundle exec rspec
# Terminal

No examples found.

Finished in 0.00031 seconds (files took 0.19956 seconds to load)
0 examples, 0 failures

If such a description appears in the terminal, RSpec has started normally, so after that, add the test code description to the file under rspec /.

Test procedure

1. Add a factories folder directly under the rspec directory and create a users.rb file in it

FactoryBot.define do

  factory :user do
    nickname        {"test"}
    email           {"[email protected]"}
    password        {"00000000"}
    family_name      {"test"}
    first_name      {"test"}
    family_name_kana    {"test"}
    first_name_kana    {"test"}
    birthday          {"2000-01-01"}
  end

end

By creating a model in factoles first and setting values, you can easily create an instance or save it in the DB by a specific method in the spec file. (You don't have to create data by entering the value for each test.)

user = FactoryBot.build(:user)

For facutoryBot, use build method or create method and specify the model added in facutories folder as an argument, and it will be the value set in ~ s.rb file.

user = FactoryBot.build(:user,  email: "")

In this way, you can override the value by adding the column name value after the model.

2 Added test description

Create a models folder in the spec directory. A file of each model is generated in it and an actual test is performed.

require 'rails_helper'
describe User do
  describe 'registrations#create' do

 it "If nickname is blank, you cannot register" do
      user = FactoryBot.build(:user, nickname: "" )  
      user.valid?
 expect (user.errors [: nickname]). to include ("Please enter") #include ("can't be blank") is correct. Since it has been converted to Japanese, it looks like the one on the left.
  end
end

This is a set of tests.

The first line is set to load spec / rails_helper.rb. On the 2nd and 3rd lines, the group of do ~ end immediately after describe represents the expression. A test expression for the registrations # create action of the user model. Immediately after it, it represents a set of test code that works, and the explanation is written in the "" that follows it. (Called example) Generate a hash on the next line and assign the value to the user variable. Use the FactoryBot method here. Specify the model name in the argument of build and overwrite the value only in the nickname column. If you use the FactoryBot method, the following will have the same value.


 it "If nickname is blank, you cannot register" do
 user = User.new (nickname: "", email: "[email protected]", password: "00000000", family_name: "test", first_name: "test", famliy_name_kana: "test", first_name_kana: "test" , birthday: "2020-01-01") #gem unused

 user = FactoryBot.build (: user, nickname: "") When using #FactoryBot

Use FactoryBotm so that it doesn't hash the value every time. Use the .valid? Method for the user variable to which the value is assigned. When saving an instance of a class that inherits ActiveRecord :: Base, check "Can it be saved by validation?". In the User model, presence: true is validated for all columns this time.

Use expect (X) .to eq Y to see if the value of the expression you put in the x part is equal to the value in the Y part. Here, the errors method is used. valid? The return value of the method is true / false, but if you use the errors method for the instance that uses the valid? Method, you can check why it cannot be saved if it cannot be saved by validation. it can.

In this case, there is no value in the nickname column, so "cant be blank" is displayed. Use the include matcher to check if the value taken as an argument is included in the array that is the argument of expect. In this case, "I know that if the nickname is empty, I get an error saying can't be blank, so write it as include (" can't be blank "). This inspection has passed, This completes the test "If the nickname is blank, it cannot be registered".

After that, add the description of the unit test and perform the test one by one.

require 'rails_helper'
describe User do
  describe 'registrations#create' do

 it "If nickname is blank, you cannot register" do
      user = FactoryBot.build(:user, nickname: "" )  
      user.valid?
 expect (user.errors [: nickname]). to include ("Please enter") #include ("can't be blank") is correct. Since it has been converted to Japanese, it looks like the one on the right.
    end

 it "If email is blank, you cannot register" do
      user = FactoryBot.build(:user, email: "")
      user.valid?
 expect (user.errors [: email]). to include (please enter "")
    end

 it "Cannot register if there is no" @ "in the email" do
      user = FactoryBot.build(:user, email: "test.gmail.com")
      user.valid?
 expect (user.errors [: email]). to include ("is an invalid value")
    end   

 it "Invalid for duplicate email addresses" do
      user1 = FactoryBot.create(:user)
      user2 = FactoryBot.build(:user)
      user2.valid?
 expect (user2.errors [: email]). to include ("already exists")
    end

 it "If password is blank, you cannot register" do
      user = FactoryBot.build(:user, password: "" )
      user.valid?
 expect (user.errors [: password]). to include (please enter "")
    end


 it "Cannot register if password is 6 characters or less" do
      user = FactoryBot.build(:user, password: "00000")
      user.valid?
 expect (user.errors [: password]). to include ("Please enter at least 6 characters")
    end


 it "If family_name is blank, you cannot register" do
      user = FactoryBot.build(:user, family_name: "" )  
      user.valid?
 expect (user.errors [: family_name]). to include (please enter "")
    end

 it "If first_name is blank, you cannot register" do
      user = FactoryBot.build(:user, first_name: "" )  
      user.valid?
 expect (user.errors [: first_name]). to include (please enter "")
    end

 it "If family_name_kana is blank, you cannot register" do
      user = FactoryBot.build(:user, family_name_kana: "" )  
      user.valid?
 expect (user.errors [: family_name_kana]). to include (please enter "")
    end

 it "If first_name_kana is blank, you cannot register" do
      user = FactoryBot.build(:user, first_name_kana: "" )  
      user.valid?
 expect (user.errors [: first_name_kana]). to include (please enter "")
    end

 it "If birthday is blank, you cannot register" do
      user = FactoryBot.build(:user, birthday: "" )  
      user.valid?
 expect (user.errors [: birthday]). to include (please enter "")
    end

  end
end

The test for validation of the user model is completed above.

References

・ Https://programming-beginner-zeroichi.jp/articles/61 ・ Https://www.sejuku.net/blog/47847 ・ Htps: // This m / shojikishindoi / n / n 5019bc64c254

Recommended Posts

[Ralis] About unit tests
Java unit tests with Mockito
Read H2 database for unit tests
About app testing RSpec (unit test)
About =
Unit tests under Active Storage deployment