Post navigation

An Introduction To RSpec

In the Ruby world, we have a few different testing libraries. One of the ones that has gained a lot of popularity and use is rspec. RSpec takes a slightly different approach to the idea of testing applications, by testing behavior rather than only specific methods. I thought I’d take some time to show everyone why rspec is so useful in testing your applications.

The Basics

RSpec gives you a way to encapsulate what you’re testing via the describe block, and it’s friend context. In a general unit testing sense, we use describe to describe the behavior of a class:

describe Hashdoend

Tests are written using the it block. Here’s an example of how you might write a spec for the Hash class:

The above code will create the @hash variable before each test is run. There are two arguments for before– all and each. Using the all argument, the setup will be done once before all of the tests in the block, and :each will be done before each individual test. The after directive has the same options and runs the same way, only after tests are completed. This is most useful when tearing down the previous state of the tests.

RSpec Idioms

We usually use the describe keyword to describe methods. Using a “.” will signify that you’re testing a class method, and using “#” will signify that it’s an instance method. Here’s how it might look for a made up class:

The context method does the same thing by letting you contextualize a block of your tests. This is extremely powerful for test states when you add more complicated setup and teardown code to really get in to your objects. I’ll show you a bit more of a real life scenario by building a delicious burger class.

Let’s say that in our Burger class we’re trying to test the #apply_ketchup method. Someone may not want ketchup on their burger. Instead of judging them, we’ll write a test for the class to not apply ketchup if someone doesn’t want it:

Cleaning Up a Bit

The above pattern works but can become a bit tiresome to repeat all the time. RSpec gives us some helper methods to generalize it. We could rewrite the above using the let keyword to make the the variable automatically. The variable would then get created the first time it is accessed:

This all works but we can clean it up even further using the subject method. The subject method tells rspec what we’re doing the tests on. We’re going to combine that with the specify method in the next example. The specify method is just like the it method except the specify method takes the code block as the description of the test:

One neat thing about rspec is that the built in matchers will let you declaratively specify methods in your tests if they conform to a certain naming convention. RSpec will look for methods that are named with has and end in a question mark to let you do write declarative test code. Here’s what our final Burger class will look like using that idiom. Put the following in a file called burger_spec.rb and run it:

A Burger Needs More Than Just Ketchup

In this brief tutorial we jumped in to rspec and created a burger class. Then we refactored our tests a bit to make them more idiomatic. What we wound up with was easier to read and quick to run. In the next tutorials in this series, we’ll delve deeper in to rspec including more idioms, further testing, and writing our own matchers. For now, I know what I’m having for lunch.

I’m not fully understanding the burger test examples. In each of the second tests, you set :ketchup to false, then apply_ketchup and expect has_ketchup it to be false. After apply_ketchup wouldn’t the burger have ketchup no matter what the initial :ketchup value was set to or am I mis-understanding something?

@5e3a78482a242c861b9111556e6724d3:disqus the point of the test is to verify that the apply_ketchup method checks the :ketchup value on the @burger instance to see if it’s true or false before applying ketchup to the burger, so that the logic doesn’t have to be applied on every usage of “apply_ketchup”. If it’s working correctly, the test will still pass.

Hi, Jason, thanks for the cool article. I didn’t know about the specify function, that’ll come in handy. Some comments…

I like how you distilled these concepts into minimal examples to illustrate how they work. As with many such minimal examples, though, I think it’s helpful to point out that the implementation shown is for illustrative purposes, and is probably only appropriate for uses more complex than the one shown.

The describe #apply_ketchup, for example, includes subject, before, let, and specify calls. ‘subject’ and ‘before’ are functions that call a method named ‘burger’, that has not yet been defined, and is, in fact defined differently in two places. To follow the flow of execution, one has a bit of jumping around to do. If burger’s modifying methods such as apply_ketchup were modified to return self, then the entire test could be written on one line:

The flow of execution is limited to one line, and is consistent with the order of the source code (i.e. left to right within the one line).

I love RSpec, I really do. 😉 It’s really cool in the way that you can write tests that are descriptive, but, like all magic, that coolness comes at a cost of a greater distance between the RSpec code you’re writing and what’s being executed under the covers. For example, I’ve had some confusion writing helper methods in various positions in an RSpec file, due to the fact that it’s not always apparent what self resolves to.

Hello! We're the teachers here at Treehouse. We produce video courses on everything from web design and web development to iOS and business skills. You can browse our full library of content to find the course that's right for you.

In the meantime, explore the free features, tips, tricks and videos here on our blog. Tell us what you think, we'd love to chat: blog@teamtreehouse.com

Stay Updated

Sign up for our newsletter, and we'll send you news and tutorials
on web design, coding, business, and more! You'll also receive these
great gifts:

checkArt and the Web: Line, Shape, and Form - An eBook by Treehouse Teacher Nick Pettit.

checkOn Freelancing - An audiobook about running your own business by Simon Collison.

Swift is a new programming language created by Apple to program iOS apps. If you are new to programming or to Swift then this course is for you. Learn about programming concepts like: variables, types, collections and control structures.

Ruby is a programming language with a focus on simplicity and productivity, and it's used to create some of the biggest websites in the world. Learn how to work with Ruby and write simple Ruby programs in this introductory course.

Interested in creating Android apps? Learn the Java programming language, a tool for Android development called Android Studio, and some very basic concepts of the Android Software Development Kit, or SDK.

Bring your big idea to life! Learn how to start a company on the right foot with an introduction to basic business concepts, including corporate structure, marketing, finance, and accounting. Then you’re ready for more advanced business strategies.