What Is Your Rails Testing Stack?
03 Sep 2012
Developing a Rails application is awesome. Why? Because the testing stack is really, really good! But, this is also a problem. There is so much to choose from, that it sometimes is really hard to figure out what is useful and what isn't.
I don't know about you, but my Gemfile tends to have a lot of stuff in the group
:development, :test.
group :development, :test do
gem 'rspec-rails'
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
gem 'capybara'
gem 'launchy'
gem 'rr'
gem 'awesome_print'
gem 'jasminerice'
gem 'guard-jasmine'
gem 'poltergeist'
end
Holy crap that's big! Of course, it also has some helpers only for development:
group :development do
gem 'guard'
gem 'libnotify'
gem 'guard-spork'
gem 'guard-cucumber'
gem 'guard-rspec'
gem 'guard-livereload'
gem 'spork'
gem 'pry-rails'
gem 'pry-stack_explorer'
gem 'pry-debugger'
end
Not too shaby, huh? So let me get into the details for each of those.
Guard
Guard is an amazing tool to automate nearly everything. Don't believe me? Take a look at all the possible
Guard extensions on Github! So what does Guard do?
It basically is a system that runs in the background and can watch files. Extensions tell it (through a
Guardfile
) that it should do something if a specific file pattern changes. For example, the
Cucumber guard checks for this:
guard 'cucumber', :cli => "--drb" do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
end
It looks at all features in the features directory, and Guard will call the Cucumber guard if one of these files changes. In term, guard-cucumber will call Cucumber and show it to you on the console. Neat, isn't it?
Of course, this isn't just for Cucumber! I also use the
RSpec guard (for RSpec tests, duh!),
Spork and
livereload.
Spork is a DRb (Distributed Ruby) server that preloads the Rails environment so the tests run faster. Adding this guard makes Guard start the DRb server for Cucumber and RSpec automatically when starting Guard itself.
Another very neat guard is guard-livereload. Thanks to an extension in Chrome, this guard will automatically reload the page I have open when I change the ERb or the CSS files. Makes fiddling with CSS a lot easier!
You Have To PRY It From My Cold Dead Hands
PRY is one of those tools that you just have to know (and love). It is an alternative to IRB, and way better! Just add a
binding.pry to your code and Pry will open in that context when the code runs over it. It allows you to change into classes and objects to inspect them more closely. And edit the methods if you want to!
Some additions I added to Pry (and there are a few
Pry plugins) are
pry-debugger, so I can step through code and see what it really does. To complement Pry Debugger, I also use
pry-stack_explorer. This plugin allows us to move up the stack and see the state of the code there.
Of course, in a perfect world, we never have to use one of these tools, but yeah... Real world and these things...
Testing tools
You might now say: "Hey! You said you will talk about
testing tools, not support tools!" And you are right! (Though these support tools are amazing for testing!)
Yes, testing tools. For my testing needs I use the standard combo
RSpec,
Cucumber,
database_cleaner,
Capybara and
rr stack. I don't think I have to explain these (Do I? If I do, you should tell me so in the comments!)
Additionally I use
launchy to launch a browser window with the current state of the page to debug Cucumber steps.
I also make copious use of
awesome_print, because it is, well, awesome! awesome_print can be used instead of
puts or
pp to output objects and have an easier time inspecting them. (Pry also can use awesome_print for it's built in printing habits!)
Last But Not Least: JavaScript Testing
Something I struggled with for a bit, but found a good solution for, is JavaScript testing. There are two aspects here: One is Cucumbers Javascript support. For some acceptance tests, I needed Javascript to run. Per default, Cucumber uses Selenium (with a real browser), which is slow and not awesome at all! And then there are the Javascript unit tests, that also need to run.
For the unit tests I settled on
Jasmine. Why? Because it seems it even tries to be as close to RSpec as possible, so I don't have to learn yet another testing system. To run them, I of course, use a guard:
guard-jasmine (Who's surprised?)
guard-jasmine uses
PhantomJS to run the Javascript tests in a headless mode (without a user interface), which makes them fast (not incredibly fast, but at least fast).
Of course we also want to integrate the Jasmine unit tests with the asset pipeline so we can use CoffeeScript. Luckily, Brad Phelan solved that problem and released
JasmineRice.
Now, this doesn't yet solve the Cucumber problem. For that, we can use
Poltergeist. Poltergeist is a PhantomJS driver for Capybara. Do you see how this neatly matches up with guard-jasmine? Nice, isn't it? I just configured Capybara to use Poltergeist instead of Selenium, and now the tests run at an acceptable rate.
So, What's Your stack?
Yes, that is my "standard" Rails testing stack. I think this covers about everything I need. One thing that's not included (because I currently don't need it) is something like
VCR. VCR records HTTP interactions, so that during testing the HTTP calls don't have to be made, but can be replayed by VCR. Which makes things even quicker.
Have I missed something? Added something superfluous? What do you use for your testing stack?
If you liked this post, you should follow me on Twitter and sign up for the RSS feed!