A few years ago I had a mistaken throught that I had to choose between focusing on development or business. It’s been a few years since I chose business, and though we’ve been doing a lot of Rails work at Atlantic Dominion Solutions, I haven’t coded anything of consequence for quite some time.
A number of weeks ago I decided to get back into Rails development, specifically the testing aspects, and being a lover of living on the bleeding edge, and seeing a few presentations on the subject, I decided to check out Rails 3. I’ve been looking for a project to do full TDD with Rails 3 on, and thanks to a friend working on a new startup, one has come my way.
Without sounding too fanboyish, I am loving Rails 3. It is much more intuitive than before, Rack is freaking awesome, and doing TDD is super easy as well, at least from the coding standpoint.
This post is going to show you how to set up a full testing stack for Rails 3, including RSpec, Cucumber, autotest, and factory girl. For the database I’m using SQLite3.
Without further ado, let’s dive into some code!
Ruby 1.9.3
Living on the bleeding edge means using unstable, in development software. I’m not risk averse, and for this project we can handle it. However sometimes you need the stable stuff, and installing and switching back and forth between versions of things can be a PITA to stay the least. This is true of Ruby. The best way currently to install multiple versions of Ruby and to switch back and forth between them is using RVM: Ruby Version Manager from Wayne E. Seguin.
For this tutorial I am using Ruby 1.9.3dev. Stable at the time of this writing is 1.9.1-p378.
To ensure that the correct version of Ruby is chosen by RVM on startup, I set 1.9.3dev as my default choice in RVM, and added the following command to the bottom of my ~/.bash_config file:
rvm default
Rails 3
Rails 3 is currently at 3.0.0beta3. Installing it is very simple. If you’re using RVM, run the following commands without using sudo:
gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
gem install rails --pre
Create A New Rails App
As with Rails 2.x, create a new rails app like so:
rails tddisbest
Make sure everything works correctly by running the built-in server.
cd tddisbest
rails server
Next fire up http://localhost:3000 in your browser of choice. Click on the “About your applications’ environment” link on the Welcome Aboard page, and if you see the following (or something close depending on your version of Ruby, you’re good to go.
Ruby version 1.9.3 (x86_64-darwin10.3.0)
RubyGems version 1.3.7
Rack version 1.1
Rails version 3.0.0.beta3
Active Record version 3.0.0.beta3
Action Pack version 3.0.0.beta3
Active Resource version 3.0.0.beta3
Action Mailer version 3.0.0.beta3
Active Support version 3.0.0.beta3
Looks like it works so let’s get it TDD ready.
RSpec-2 for Rails 3
First up is to get RSpec-2 working. This is an updated version of the very popular RSpec testing framework that works with Rails3 beta, and as I write this the latest version is 2.0.0.beta.10. Install it using this command:
gem install rspec-rails --pre
I also deleted the default test directory that Rails gives us. Once the gems are installed, add the following lines to the Gemfile file in your Rails app:
gem "rspec-rails", ">= 2.0.0.beta.10", :git => "git://github.com/rspec/rspec-rails.git"
gem "rspec", ">= 2.0.0.beta.10", :git => "git://github.com/rspec/rspec.git"
gem "rspec-core", ">= 2.0.0.beta.10", :git => "git://github.com/rspec/rspec-core.git"
gem "rspec-expectations", ">= 2.0.0.beta.10", :git => "git://github.com/rspec/rspec-expectations.git"
gem "rspec-mocks", ">= 2.0.0.beta.10", :git => "git://github.com/rspec/rspec-mocks.git"
To ensure that the gems get packed up with your Rails app, run the following bundler command to install them:
bundle install
Once the gems are all bundled up, install RSpec into your Rails app with the following command:
rails g rspec:install
That little “g” after the rails command stands for “generate.” I’m not sure when Rails added this or if it’s always been there, but being lazy I like that I don’t have to type “generate” ever again.
Now, to test that it’s working properly, you’ll need to create a table in your database, run the migrations, and then run the rake spec command to test. I generated some scaffolding for a product, just for kicks.
rails g scaffold Product name:string description:text price:decimal
rake db:migrate
rake spec
If everything is working properly you should get something similar to this output:
Finished in 1.05 seconds
22 examples, 0 failures, 2 pending
Done. If you want some nice colored goodness, install the redgreen gem.
Next up is Cucumber. Yay!
Cucumber
To get the latest version of Cucumber running so we can test Rails 3 app writing tests from our user stories, add the following lines to your Gemfile:
gem 'capybara'
gem 'database_cleaner'
gem 'cucumber-rails'
gem 'cucumber', '0.7.3'
gem 'spork'
gem 'launchy'
To install the gems locally, run bundle install. Now bootstrap your Rails app with the following command:
rails g cucumber:skeleton --rspec --capybara
This command tells Cucumber to use RSpec and Capybara (a webrat alternative).
To test that Cucumber is functioning properly, run:
rake cucumber
Everything being set up correctly, we get the following output of the command:
Using the default profile...
0 scenarios
0 steps
0m0.000s
So far so good. We’ve got Ruby 1.9.3, Rails 3, RSpec, and Cucumber all up and running properly. Next we’ll get autotest going and finally replace those icky fixtures that are so brittle.
Autotest
Getting autotest up and going is a very simple matter. One thing to note is that with Rails 3, or perhaps Mac OS X 10.6.3, or the latest Ruby, is that I didn’t have to set up anything in my bash profile or write an autotest config file in my app. All I did was add the gems to my Gemfile, run bundle install, and then run autotest at the command line. Once I did that I got the following output:
# RSpec Output
Finished in 0.23307 seconds
21 examples, 0 failures, 2 pending
# Cucumber Output
Using the default profile...
0 scenarios
0 steps
0m0.000s
If you see some other output don’t worry for now – we don’t have any real tests to run. We’ll do those at a later date, but still before we write any more code.
Have I mentioned yet how much I love Ruby and Rails? Freaking awesome. Now, let’s put a little Factory Girl into our app.
Factory Girl
Factory Girl is an excellent plugin from thoughtbot that uses the factory pattern to replace fixtures and make our test much more readable. To get it going with Rails 3, add the following line to your Gemfile:
gem 'factory_girl', :git => 'git://github.com/thoughtbot/factory_girl.git', :branch => 'rails3'
Next run bundle install and you’re almost done. Add this little line to your spec/spec_helper.rb file to make the factories available to all of your specs:
require 'factory_girl'
If you don’t already have it, create a ‘factories’ folder in the spec folder to hold, you guessed it, your factories.
Done!
And that my friends, is it. We now have a complete local environment ready to roll for TDD (test driven development). Next on my agenda is to set up a continuous integration server. We’ve been using Cruise Control, however I hear there are a few other ones out there I should check out, including Integrity and Hudson.
Now get out there and test your code!
Other Posts That Might Interest You