DEV Community

Cover image for Introduction to RSpec
Raymundo Alva
Raymundo Alva

Posted on

Introduction to RSpec

RSpec is a domain-specific language (DSL) testing tool that was created to test ruby code. The idea is to write tests first and then write just enough code to pass the tests and then follow with refactoring. Since RSpec is a behavior driven development (BDD) test tool it focuses on describing what an application does and whether it follows a specification. RSpec is meant to be really easy to read. Adopting a test driven approach will make you a better developer because it forces you to think critically about the program and its features. Today I am going to show you how easy it is to get started writing tests using RSpec.

First we are going to start by making sure that RSpec is installed. This is very simple, just install the RSpec gem with this command.

$ gem install rspec
Enter fullscreen mode Exit fullscreen mode

Now we have rspec installed and we can generate some configuration files. First create and go into a directory. Then we are going to run a command that will create the configuration files.

$ mkdir rspec\_example  
$ cd rspec\_example/  
$ rspec --init
Enter fullscreen mode Exit fullscreen mode

This command will create two files, the first is inside a folder named spec called spec_helper.rb and the other is .rspec. Inside this spec folder is where we will be writing our tests. We can start with an easy example. Let’s try to do a greeting program that will take in a name and greet you. First let’s create a ruby file in the main directory and a greeting spec file inside the spec folder.

$ touch greeting.rb  
$ touch spec/greeting\_spec.rb
Enter fullscreen mode Exit fullscreen mode

In the greeting.rb file we are going to create a greeting class that will be initialized with a name.

class Greeting  
  def initialize(name)  
    @name = name  
  end  
end
Enter fullscreen mode Exit fullscreen mode

Now by following test driven development lets write a test to implement the greeting. We want the Greeting class to have a method that will greet when called. Lets start building the test skeleton for our greeting_spec.rb.

require './greeting'

RSpec.describe Greeting do  

end
Enter fullscreen mode Exit fullscreen mode

First we require ‘./greeting’. In a test file, we are describing the behavior of the class. For RSpec to know what class we are dealing with we have to wrap the test definition with an RSpec.describe block. It is important to know that the name of the class is not mandatory and can be replaced with a string if you would like. The word describe is an RSpec keyword and it is used to describe a “Example Group”, which can be thought of as a collection of tests. For our program we want a method that will give a greeting with a name included. So now we can start describing the method.

require './greeting'

RSpec.describe Greeting do  
  describe '#greet\_me' do  
    it 'prints a greeting with the name' do

    end  
  end  
end
Enter fullscreen mode Exit fullscreen mode

The ‘it’ keyword is used to define an ‘Example’ which is our test. Just like describe, it accepts a class name or string argument and should be used with a block argument. Inside this block is where we will test the behavior of our program. We want to create a new instance of the Greeting class and call the greet_me method on it. Then we should expect it to output the greeting. Our test will look like this now.

require './greeting'

RSpec.describe Greeting do  
  describe '#greet\_me' do  
    it 'prints a greeting with the name' do  
      greeting = Greeting.new('Ray')  
      expect(greeting.greet\_me).to eq('Hello Ray')  
    end  
  end  
end
Enter fullscreen mode Exit fullscreen mode

The expect keyword in RSpec is used to define an ‘Expectation’. This is the step where we check if a certain expectation has been met. The .eq method is referred to as a matcher. When the greet_me method is called and the output is equal to ‘Hello Ray’ the test will pass. The syntax is very easy to read and almost reads exactly as plain English. Go ahead an run the rspec command on the terminal and you will see something like this.

Failures:

1) Greeting#greet\_me prints a greeting with the name  
     Failure/Error: expect(greeting.greet\_me).to eq('Hello Ray')  

     NoMethodError:  
       undefined method \`greet\_me' for #<Greeting:0x00005639ee5775c8 [@name](http://twitter.com/name "Twitter profile for @name")\="Ray">  
     # ./spec/greeting\_spec.rb:7:in \`block (3 levels) in <top (required)>'

Finished in 0.00139 seconds (files took 0.06321 seconds to load)  
1 example, 1 failure
Enter fullscreen mode Exit fullscreen mode

The test didn’t pass because we don’t have a greet_me method defined. So let’s go step by step and create a method named greet_me in the greeting.rb file.

class Greeting  
  def initialize(name)  
    @name = name  
  end

  def greet\_me  

  end  
end
Enter fullscreen mode Exit fullscreen mode

Now that we have the method defined run rspec again and you will notice that the error looks like this.

Failures:

1) Greeting#greet\_me prints a greeting with the name  
     Failure/Error: expect(greeting.greet\_me).to eq('Hello Ray')  

       expected: "Hello Ray"  
            got: nil  

       (compared using ==)  
     # ./spec/greeting\_spec.rb:7:in \`block (3 levels) in <top (required)>'

Finished in 0.01522 seconds (files took 0.06191 seconds to load)  
1 example, 1 failure
Enter fullscreen mode Exit fullscreen mode

The error tells you that it expects to see “Hello Ray” but instead it got nil. You may be able to see how this feedback loop can be helpful in building your code. Now that we know what the next step is let’s get the test passing. Let’s add this to our code.

class Greeting

  def initialize(name)  
    @name = name  
  end

  def greet\_me  
    "Hello #{@name}"  
  end

end
Enter fullscreen mode Exit fullscreen mode

Now when we run RSpec you can see that all of the tests have passed!

Finished in 0.00151 seconds (files took 0.06547 seconds to load)  
1 example, 0 failures
Enter fullscreen mode Exit fullscreen mode

Tests are also a great part of documentation. You can run a command that will show you what a method is responsible for. That way if someone is new to the project and wants to know more about the Greeting class they can see how it behaves.

$ rspec --format documentation  
Enter fullscreen mode Exit fullscreen mode
Greeting  
  #greet\_me  
    prints a greeting with the name

Finished in 0.00095 seconds (files took 0.06487 seconds to load)  
1 example, 0 failures
Enter fullscreen mode Exit fullscreen mode

Testing will help you with making sure that your code behaves exactly the way you want it to. This process will also make you a better developer. Experience in RSpec is mentioned in most job offers, so it’s valuable knowledge and may be beneficial for you if you plan to work as a Ruby developer. Have fun writing tests and happy coding! 😎

Top comments (0)