[RAILS] RSpec Basics

What is RSpec

▶ A test framework used in Ruby on Rails. By making good use of RSpec, you can write concise and easy-to-read test code and improve the maintainability of your Rails application. ▶ By the way, Ruby on Rails has a test framework called Minitest built in as standard, but I haven't learned it yet, so I'd like to post about RSpec this time.

1. RSpec initial settings

Add RSpec Gem to Gem file

# Gemfile
group :development, :test do      #Write in the development / test group to limit Gem operation
       #abridgement
  gem 'rspec-rails', '~> 4.0.0'   #← Addition of gem
end

Run bundle install in the terminal

Move to the application directory and execute the following command
% bundle install

Continue to install RSpec

% rails g rspec:install

After the installation is complete, the following directories and files will be generated.

Terminal log
Running via Spring 
preloader in process 1087
   create .rspec
   create spec 
   create spec/spec_helper.rb
   create spec/rails_helper.rb

You can also visualize the test code results in the terminal by adding the following to the generated .rspec.rb.

# spec/.rspec.rb
--format documentation

This completes the initial settings. Next, I would like to actually write the test code.

2. Write a simple test code with RSpec

Now I would like to write test code. Spec files are placed in subdirectories of the spec directory. It is customary to put what spec files in which subdirectories. For example, the spec file for model classes is in the spec/models directory , and the spec file for API is in the spec/requests directory. It is common to put it in.

This time, I will create a tests directory as a subdirectory for explanation. Create a subdirectory of the tests directory in the spec directory , and create a string_spec.rb file directly under it. At this time, you don't have to worry about the file name, but the end of the file should be _spec.rb .

Test if the characters are added correctly

# spec/tests/string_spec.rb
require "spec_helper"

describe String do
  it "Add characters" do
    str = "Ah"                 #Define variable str
    str << "e"                  #to str"e"Add
    expect{str.size}.to eq(4)   #Check the state of the variable str with the expect method. After adding characters, the number of characters is 4 ("AIUE")
  end
end

describe method

A method for grouping test code. Group "Which function to test for" with describe, and write each test code in it. The part surrounded by describe and end is called Exemple Group . Specify the class or character string in the argument of the describe method. The example group can be nested.

it method

Like the describe method, it is a method for grouping. In the case of it, specify "what kind of situation is to be tested in the function described in the describe method" in more detail. There is also a usage called example, which refers to a group divided by it. It may also refer to the content described in it.

expectation

Expectation is a syntax that confirms that the behavior obtained by verification is as expected. Using expect (T) .to M as a template, change T (argument) and M (matcher) according to the content of the test. Describe.

matcher

The matcher determines if the "expect argument" and the "expected behavior" match. In the argument of expect, specify the actual behavior obtained by verification, and in the matcher, describe what kind of behavior is expected. This time, I am using eq matcher. eq is a matcher that ensures that the "expect argument" and the "eq argument" are equal.

Now let's run the test code in the terminal.

Terminal
% bundle exec rspec spec/tests/string_spec.rb

The log looks like this: The test is successful .

Finished in 0.01423 seconds (files took 0.15324 seconds to load)
1 example, 0 failures

If it fails

Next, let's look at In case of failure . The additional characters are "Eo".

# spec/tests/string_spec.rb
require "spec_helper"

describe String do
  it "Add characters" do
    str = "Ah"                 #Define variable str
    str << "Eo"                  #to str"Eo"Add
    expect{str.size}.to eq(4)   #Check the state of the variable str with the expect method. After adding characters, the number of characters is 5 ("AIUEO")
  end
end

The log looks like this: The test is failed .

String
Add characters(FAILED - 1)

Failures:

  1)Add String character
     Failure/Error: expect(s.size).to eq(4)
     
       expected: 4
            got: 5
     
       (compared using ==)
     # ./spec/tests/string_spec.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.03041 seconds (files took 0.13182 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/tests/string_spec.rb:4 #Add String character

At this time, "Failure/Error: expect (s.size) .to eq (4)" followed by "expected: 4 got: 5" There is an error message saying that it is supposed to be 4 characters, but it is actually 5 characters. If the test fails in this way, the log will give you a hint of what caused the failure.

3. Pending method

Basically, you'll have to modify the source code and run the tests until all the tests are successful. However, there are times when you cannot fix it immediately because you do not know the cause or you do not have enough time. In that case, you can use the pending method to mark the example as "pending".

require "spec_helper"

describe String do
  it "Add characters" do
      pending("investigation in progress")    #Give an argument to the pending method to indicate the reason. in this case"investigation in progress"
      s = "Ah"
      s << "Eo"
      expect(s.size).to eq(4)
  end
end

If you run the test in this state, it will look like this:

String
Add characters(PENDING:investigation in progress)

Pending: (Failures listed here are expected and do not affect your suite's status)

  1)Add String character
     #investigation in progress
     Failure/Error: expect(s.size).to eq(4)
     
       expected: 4
            got: 5
     
       (compared using ==)
     # ./spec/tests/string_spec.rb:8:in `block (2 levels) in <top (required)>'

Finished in 0.0292 seconds (files took 0.13358 seconds to load)
1 example, 0 failures, 1 pending

There is also a xexampl method instead of the pending method. I'm not using example this time, but I simply rewrite the target example to xexample. This will print "Temporarily disabled with xexample" in the terminal log, which means "temporarily disabled by xexample".

4. Narrow down the example

Example test code with multiple example groups

# spec/tests/test_spec.rb
require "spec_helper"

describe String do                   #Line number 3
  it "Add characters" do
      s = "Ah"
      s << "e"
      expect(s.size).to eq(4)
  end
end

describe Integer do                  #Line number 11
  it "Addition of numbers" do
      i = 1
      i += 1
      expect(i).to eq(2)
  end
end

When running test code with multiple example groups, it can be time consuming and you may want to test only a specific example room.

Narrow down by line number

Specify a colon (:) and a line number after the path as follows: This time we will only execute the example group with line number 11.

Terminal
 % bundle exec rspec spec/tests/test_spec.rb:11
Terminal log
Run options: include {:locations=>{"./spec/tests/string_spec.rb"=>[11]}}

Integer
Addition of numbers

Finished in 0.0039 seconds (files took 0.13787 seconds to load)
1 example, 0 failures

Narrow down by tag

Modify test_spec.rb as follows:

# spec/tests/test_spec.rb
require "spec_helper"
    #Omitted on the way#
describe Integer do                  #Line number 11
  it "Addition of numbers" , :exception do    # [, :exception]Addendum
      i = 1
      i += 1
      expect(i).to eq(2)
  end
end

The tag is the symbol: exception added to the second argument of the example method. That way, you can run only the exceptions with the: exception tag in bulk with the following command:

Terminal
 % bundle exec rspec spec/tests/test_spec.rb --tag=exception
Terminal log
Run options: include {:exception=>true}

Integer
Addition of numbers

Finished in 0.004 seconds (files took 0.15853 seconds to load)
1 example, 0 failures

I was able to run only one of the two Exemple groups. This time there are only two, but in actual application development, we may write test code by dividing it into a large number of example groups. When you modify the code in one example group and test it again, it is inefficient to test the other example group. Therefore, I think it is important to narrow down the example.

Finally

This time I posted about the basics of RSpec. I have actually executed the introduced code and tried to see if there are any mistakes, but if there are any mistakes, please point them out.

Recommended Posts

RSpec Basics
Rspec Basics [Rails]
RSpec setup
Ruby basics
Ruby basics
Introducing RSpec
Fragment basics
JPA Basics 1
Docker basics
ViewPager basics
RSpec preparation
Java basics
Java basics
RSpec Setup
Rspec, TDD (1)
JavaScript basics
Hello RSpec
JPA Basics 2
Hash basics
Java basics
Ruby basics
RecyclerView Basics
Rails database basics
Rails Logger Basics
java programming basics
Java JAR basics
Object-oriented (Java) basics
vim (gitbush) basics
Regular expression basics
Java concurrency basics
[Rails5] Rspec -validation-
Stream API basics
About RSpec (Rails)