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:
- describe,
- it,
- and expect .
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.