RSpec - Filtering



You may want to read the section on RSpec Metadata before reading this section because, as it turns out, RSpec filtering is based on RSpec Metadata.

Imagine that you have a spec file and it contains two types of tests (Examples): positive functional tests and negative (error) tests. Let’s define them like this −

RSpec.describe "An Example Group with positive and negative Examples" do 
   context 'when testing Ruby\'s build-in math library' do
      
      it 'can do normal numeric operations' do 
         expect(1 + 1).to eq(2) 
      end 
      
      it 'generates an error when expected' do
         expect{1/0}.to raise_error(ZeroDivisionError) 
      end
      
   end 
end

Now, save the above text as a file called ‘filter_spec.rb’ and then run it with this command −

rspec filter_spec.rb

You will see output that looks something like this −

.. 
Finished in 0.003 seconds (files took 0.11201 seconds to load) 
2 examples, 0 failures

Now what if, we wanted to re-run only the positive tests in this file? Or only the negative tests? We can easily do that with RSpec Filters. Change the above code to this −

RSpec.describe "An Example Group with positive and negative Examples" do 
   context 'when testing Ruby\'s build-in math library' do
      
      it 'can do normal numeric operations', positive: true do 
         expect(1 + 1).to eq(2) 
      end 
      
      it 'generates an error when expected', negative: true do 
         expect{1/0}.to raise_error(ZeroDivisionError) 
      end
      
   end 
end

Save your changes to filter_spec.rb and run this slightly different command −

rspec --tag positive filter_spec.rb

Now, you will see output that looks like this −

Run options: include {:positive=>true} 
. 
Finished in 0.001 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

By specifying --tag positive, we’re telling RSpec to only run Examples with the: positive metadata variable defined. We could do the same thing with negative tests by running the command like this −

rspec --tag negative filter_spec.rb

Keep in mind that these are just examples, you can specify a filter with any name that you want.

RSpec Formatters

Formatters allow RSpec to display the output from tests in different ways. Let’s create a new RSpec file containing this code −

RSpec.describe "A spec file to demonstrate how RSpec Formatters work" do 
   context 'when running some tests' do 
      
      it 'the test usually calls the expect() method at least once' do 
         expect(1 + 1).to eq(2) 
      end
      
   end 
end

Now, save this to a file called formatter_spec.rb and run this RSpec command −

rspec formatter_spec.rb

You should see output that looks like this −

. 
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

Now run the same command but this time specify a formatter, like this −

rspec --format progress formatter_spec.rb

You should see the same output this time −

. 
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

The reason is that the “progress” formatter is the default formatter. Let’s try a different formatter next, try running this command −

rspec --format doc formatter_spec.rb

Now you should see this output −

A spec file to demonstrate how RSpec Formatters work 
   when running some tests 
      the test usually calls the expect() method at least once
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

As you can see, the output is quite different with the “doc” formatter. This formatter presents the output in a documentation-like style. You might be wondering what these options look like when you have a failure in a test (Example). Let’s change the code in formatter_spec.rb to look like this −

RSpec.describe "A spec file to demonstrate how RSpec Formatters work" do 
   context 'when running some tests' do 
      
      it 'the test usually calls the expect() method at least once' do 
         expect(1 + 1).to eq(1) 
      end
      
   end 
end

The expectation expect(1 + 1).to eq(1) should fail. Save your changes and re-run the above commands −

rspec --format progress formatter_spec.rb and remember, since the “progress” formatter is the default, you could just run: rspec formatter_spec.rb. You should see this output −

F 
Failures:
1) A spec file to demonstrate how RSpec Formatters work when running some tests 
the test usually calls the expect() method at least once
   Failure/Error: expect(1 + 1).to eq(1)
	
      expected: 1
         got: 2
			  
      (compared using ==)			  
   # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)>'

Finished in 0.016 seconds (files took 0.11201 seconds to load)
1 example, 1 failure
Failed examples:

rspec ./formatter_spec.rb:3 # A spec file to demonstrate how RSpec 
   Formatters work when running some tests the test usually calls 
   the expect() method at least once

Now, let’s try the doc formatter, run this command −

rspec --format doc formatter_spec.rb

Now, with the failed test, you should see this output −

A spec file to demonstrate how RSpec Formatters work
   when running some tests
      the test usually calls the expect() method at least once (FAILED - 1)
		
Failures:

1) A spec file to demonstrate how RSpec Formatters work when running some
   tests the test usually calls the expect() method at least once
   Failure/Error: expect(1 + 1).to eq(1)
	
   expected: 1
        got: 2
		  
   (compared using ==)
   # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)>'
	
Finished in 0.015 seconds (files took 0.11401 seconds to load) 
1 example, 1 failure

Failed Examples

rspec ./formatter_spec.rb:3 # A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once.

RSpec Formatters offer the ability to change the way test results display, it is even possible to create your own custom Formatter, but that is a more advanced topic.

Advertisements