Running the Test

Learn how to run tests on rails application and workflow of running RSpec example group.

Gatherer app’s first test

Now that we’ve written our first test, we’d probably like to execute it. Although RSpec provides Rake tasks for executing RSpec, use the rspec command directly to avoid the overhead of starting up Rake. If we use rspec with no arguments, RSpec will run over the entire directory. See Running Tests Faster and Running Faster Tests for details on those options.

What happens when the test is run?

It fails. We haven’t written any code yet.

What really happens—internally?

When we run rspec with no arguments, RSpec loads every file in the spec directory. The following things happen (this process is slightly simplified for clarity):

  1. Each file in the spec directory is loaded. Usually, these files will contain these specs, but we’ll sometimes define a setup, additional helper methods, or dummy classes that exist only to support the tests.

  2. Each RSpec file typically requires the rails_helper.rb file. The rails_helper.rb file loads the Rails environment itself, as well as the spec_helper.rb, which contains a non-Rails rspec setup. In the default Rails configuration, the .rspec file automatically loads spec_helper.rb. We could also change the .rspec file to load rails_helper.rb automatically.

  3. By default, the rails_helper.rb file sets up transactional fixtures. Fixtures is a Rails mechanism that defines global Active Record data that is available to all tests. By default, fixtures are added once inside a database transaction that wraps all the tests. At the end of the test, the transaction is rolled back, allowing the next test to continue with a pristine state. To learn more about fixtures, refer to this lesson.

  1. Each top-level call to RSpec.describe creates an internal rspec object called an example group. The creation of the example group causes the block argument to describe to be executed. This may include further calls to describe to create nested example groups. The block argument to describe may also contain calls to it. Each call to it results in the creation of an individual test, which is internally called an “example.” The block arguments to it are stored for later execution.

  2. Each top-level example group runs. By default, the order in which the groups run is random. The randomness is to discourage using a global state that might inadvertently make tests dependent on earlier tests. Before running examples in the example group, run any before(:all) blocks. These blocks allow us to create a global setup for all examples in the group. Like anything that contains a global setup in tests, they are prone to failure and should be used sparingly.

RSpec examples and example groups

Running an example group involves running each example that it contains, and that involves a few steps that are detailed below:

  1. Run all before(:example) setup blocks. We’ll learn more about those in a moment when they become useful.

  2. Run the example, which is the block argument to it. The method execution ends when a runtime error or a failed assertion is encountered. If neither of those happens, the test method passes. Yay!

  3. Run all after(:example) teardown blocks. Teardown blocks are declared similarly to setup blocks, but their use is much less common.

  4. Rollback or delete the fixtures as described earlier. Each example is passed back to the test runner for display in the console or IDE window running the test.

  5. After all examples in the file have run, run any after(:all) blocks.

The following diagram shows the flow:

Get hands-on with 1400+ tech skills courses.