So far we’ve added a good amount of test coverage to our contacts manager. We got RSpec installed and configured, used factories to generate test data, and set up some unit tests on models and controllers. Now it’s time to put everything together for integration testing—in other words, making sure those models and controllers all play nicely with other models and controllers in the application. These tests are called request specs in RSpec—and yes, they can be daunting if you’re still getting comfortable with testing.
The good news is you know almost everything you need to know to write a solid request spec—they follow the same describe
and context
structure you’ve been using in models and controllers, and you can use Factory Girl to generate test data for them.
There’s one last component to complete the basic RSpec toolkit: Capybara. If necessary, add Capybara (and another gem we’ll use in a moment, DatabaseCleaner) to your Gemfile’s :test
group like so, running bundle install
to install the dependencies:
Capybara lets you simulate how a user would interact with your application through the web, using a series of easy-to-understand methods like click_link
, fill_in
, and visit
. What these methods let you do, then, is describe a test scenario for your app—for example:
You should recognize some techniques from previous tutorials—describe
puts some structure to the spec (we can break things down further with more context
, too) and the expect{}
Proc we checked out in the controller specs tutorial plays the same role here. Following the Proc, we run a series of tests to make sure the resulting view is displayed in a way we’d expect, using Capybara’s not-quite-plain-English-but-still-easy-to-follow style. Check out, too, the within
block used to specify where to look on a page for specific content— in this case, within the <h1>
tag in the show
view for contacts. You can get pretty fancy with this if you’d like—more on that in just a moment.
One other thing to point out: Within request specs, I think it’s perfectly reasonable to have multiple expectations in a given example. Request specs typically have much greater overhead than your models and controllers, and as such can take a lot longer to run.
Of course, we need to load Capybara into RSpec to make it work, so open your spec/spec_helper.rb
file and add the following, below any other require
statements you’ve got there (and while you’re at it, go ahead and require DatabaseCleaner, assuming you added it to your Gemfile and installed the gem already—if not, do that first):
So we’ve verified (with a passing spec) that our user interface for adding contacts is working as planned. Let’s get slightly more complicated—this time we’ll add a contact, then use the web interface (via Capybara) to delete it. The spec should look something like this:
Nothing too complex there—but what if we’d like to verify we’ve got the Javascript confirmation dialog wired up correctly? Luckily, Capybara bundles support for the Selenium web driver out of the box. With Selenium, you can simulate web interactions, including Javascript, through a copy of Firefox loaded on your computer. Here’s what the modified spec looks like:
Notice what’s different: We’ve added js: true
to the example, to tell Capybara to use a Javascript-capable driver (Selenium, by default). We’ve also added a couple of lines within expect{}
to tell Capybara what to do with the dialog when it pops up.
One more new item: The call to DatabaseCleaner.clean
in the first line of the example. Typically, RSpec is good about cleaning out your test database for each example, but when you use Selenium you’ll need to help it out a bit. That’s where DatabaseCleaner comes into play. However, you’ll need to tell RSpec to use DatabaseCleaner’s truncation “strategy” instead of RSpec’s default technique for resetting test data.
Open spec/spec_helper.rb
again locate the line:
Comment that line out. Below it, paste the following replacement strategy:
With those changes, the request spec will run through Firefox (amaze your friends as the browser launches and works through the steps of your web interface), and you’re one step closer to a well-tested application.
You’ve now got all the tools you need to do basic automated testing in your Rails projects, using RSpec, Factory Girl, Capybara, and DatabaseCleaner to help. These are the core tools I use daily as a Rails developer, and the tutorials I’ve presented here show how I learned to effectively use them to increase my trust in my code. I hope I’ve been able to help you get started with these tools as well.
There’s a lot we haven’t covered, though:
I’m happy to announce that I’m working on a book to cover these topics! There will be more details in the coming days, but I’m self-publishing to keep it affordable (under 10 American bucks) and intend to provide a complete source example and updates through Rails 4.0. Get early access now!
Ruby on Rails news and tips, and other ideas and surprises from Aaron at Everyday Rails. Delivered to your inbox on no particular set schedule.