Skip to content

What is RSpec? How do I create unit tests for Ruby code?

DeeDeeG edited this page Jun 24, 2020 · 6 revisions

RSpec Tests Ruby Code

Each RSpec file contains one or more tests. Each test ensures a particular feature of our website is working properly.

The output of an RSpec run will tell you exactly what features aren't working. The benefit is that tested code is unlikely to break unnoticed.

The tests are run every time someone makes, or updates, a Pull Request.

Example: See our RSpec pass or fail status: Pull Request #316, Fix-Heroku, March 27th 2017

RSpec Functions

first, a note about do and end

Every do corresponds with an end somewhere later in the file.

You can think of do as a left bracket "{" and think of end as a right bracket "}" that encloses some line(s) of code. This keeps code logically separated, so one test doesn't leak into the other.

RSpec has its own functions that help make tests work. Some basic ones are as follows.


  • RSpec.describe marks the beginning of a test. It also gives the test a name, such as: #rating_percentage.

  • RSpec.context creates a shared context for sub-tests to run in, as part of an existing, larger test. It also optionally adds a line of text that helps explain (and give context to) the subtest. (This line of text is optional, but can make the tests easier to understand.) Example: 'it returns the rating percentage'.

  • RSpec.it lays out an "example," or an actual bit of a test, in Ruby code that should evaluate to TRUE. It uses a do command to start a block of lines of test code. The block is finished with an end command. If none of the code in the test errors out, and it all returns TRUE, the test passes.

    • Usually, the block of code for Rspec.it ends with an "assertion" or "expectation", for example: expect(restroom.rating_percentage).to eq 0. If the expectation matches with the actual result during testing, the example passes. Otherwise, the example fails, and the larger test it is part of also fails.
    • The RSpec.it line can start with a line of text that describes how the test result should be, if the test passes. Descriptive text is usually a good idea, to help keep the tests easy to read for the next person who comes around. This text is optional, so some tests do not include it. Example RSpec.it line:

Example test:

  describe '#rating_percentage' do
    context 'it returns the rating percentage' do
      it 'should return 0 when there are no votes' do
        expect(restroom.rating_percentage).to eq 0
      end

Reading the tests requires some understanding of how programming languages determine true and false values. (Ruby is written in an English-like way, though, so some tests may be intuitive even to folks who have never coded.)

Show me the files!

Alright, here you go: https://github.com/RefugeRestrooms/refugerestrooms/blob/develop/spec/

What's Behavior Driven Development?

Behavior Driven Development, aka Test Driven Development, is a philosophy of coding that started with the notion that all code should be covered with small tests for each feature ("unit tests"). And if every feature must have tests, why not write the tests first, to define your features, then code the features until the tests work?

BDD/TDD suggests we ought to begin with a test file, and grow out our app from there. It's a radical idea. But, thankfully, we can still use their test-writing programs (in this case RSpec) the traditional way, which is writing the code first, tests later.

Further reading