Home /

Notes to self /

Rails testing, with rspec

Rails testing, with rspec

It's a 9 minute read

Testing in any language is pretty much one of the most vital parts in development. Without it, applications could be fragile and rigid, most likely breaking whenever you try to add a new feature.

This is why learning how to test your code is a vital skill coding skill you need to have. Today, we’ll be taking a look at the basics of coding in Ruby using TDD (test-driven development) .

What is being used to test in Ruby?

Rspec is possibly the most widely used testing tool in Ruby. If you are going to be learning how to test in Ruby, this is the main tool that you should focus on. Rspec is a domain specific language (DSL) and is a perfect tool to use for testing in test-driven development.

How do you install it?

To install Rspec into a new project, just follow the steps below.

Firstly create a folder. This is where all your files will live. From your terminal, you can create a new folder for this project and name it rspec_tutorial:

mkdir rspec_tutorial

Then you should cd into that folder.

cd rspec_tutorial

Now create a gemfile in your project folder. Note how it is capitalised and that there is no suffix.

touch Gemfile

Next, add the following code into your gemfile by copy and pasting the code below.

source 'https://rubygems.org'
gem 'rspec'

Now we run bundle install from your terminal while still in the project directory. All done! Your project is now set up to use Rspec!

What are the basics of Rspec?

The basics of an Rspec file contain 3 main sections:

Of course, there is much more to Rspec, but you can start writing tests with just these 3. I’ll detail the whole test below and then we can break it down afterwards.

The example below will be testing a file that has a class Dog and it has a function #bark that prints out the string Woof! Very important to note that none of that code has been written yet. In test-driven development, we write out the tests first before writing any tests.

First, let’s create a file to house all our tests. We usually split up our tests for every file we create. Since we are expecting to create a dog.rb file for our Dog class, we are going to create a dog.spec.rb file. This is the convention we will follow.

Lets build our test

To create the file, input the following terminal command: touch dog.spec.rb

Now you just copy and paste this into your dog.spec.rb file.

require 'rspec'
require_relative 'dog'

describe Dog do
  describe '#bark' do
    it 'returns the string "Woof!"' do
      expect(subject.bark).to eql('Woof!')
    end
  end
end

We can start at the top and talk about the first two lines:

require 'rspec'
require_relative 'dog'

Here, we are just allowing the file to have rspec functionality with require 'rspec'. The second line is importing in the file that we are testing: require_relative 'dog'. Note how you don’t need to add the extension .rb when using require_relative.

The next line starts out the scope of our test, and that will be the Dog class.

describe Dog do

Within the Dog class, we are going to describe the method we are testing for like this

describe Dog do
  describe '#bark' do

Now, we are going to describe what the method is meant to do

describe Dog do
  describe '#bark' do
    it 'returns the string "Woof!"' do

Finally, we write out the expectation of what the result is. We wrap the method call in an expect wrapper and declare what it is to equal.

describe Dog do
  describe '#bark' do
    it 'returns the string "Woof!"' do
      expect(subject.bark).to eql('Woof!')
    end
  end
end

Now, when you run the following code, you will see the test pass or fail: rspec dog.spec.rb

This will fail because there is no Dog class with a #bark method. Simply add the following code into a new file called dog.rb.

An error occurred while loading ./dog.spec.rb.
Failure/Error: require_relative 'dog'

LoadError:
  cannot load such file -- /Users/r3id/Documents/code/learning/rspec_tutorial/dog
# ./dog.spec.rb:2:in `require_relative'
# ./dog.spec.rb:2:in `<top (required)>'
No examples found.


Finished in 0.00003 seconds (files took 0.15926 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

Lets build our code!

Firstly you will need to create the file from your terminal: touch dog.rb

Then paste the following code into there:

class Dog
  def bark
    "Meow!"
  end
end

Run rspec dog.spec.rb again to see if your tests pass or fail.

F

Failures:

  1) Dog#bark returns the string "Woof!"
     Failure/Error: expect(subject.bark).to eql('Woof!')

       expected: "Woof!"
            got: "Meow!"

       (compared using eql?)
     # ./dog.spec.rb:7:in `block (3 levels) in <top (required)>'

Finished in 0.02639 seconds (files took 0.10972 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./dog.spec.rb:6 # Dog#bark returns the string "Woof!"

As you can see your test failed. We were expecting the string “Woof!” to be returned, but instead we got “Meow!”.

So make a quick edit to your bark method, and change "Meow!" to "Woof!" the re-run rspec dog.spec.rb.

Your tests should now all pass!

Finished in 0.00827 seconds (files took 0.18086 seconds to load)
1 example, 0 failures

And finally…

As you can see Rspec is an easy tool to use. Don’t let testing intimidate you or hold you back from writing clean applications. While it will take more time to initially build your applications, you’ll find that you’ll be save a lot of time in the long run.

You can download the source code for this at the following Gist

Further reading

I will add more articles here which are worth a read to further you Rspec learning.

Privacy

© 2023 Alan Reid