Testing your Rails 2.3.9 Gem plugin with rspec
Sunday, November 14, 2010 at 8:19AM OS: OS X 10.6.4
Ruby: ree-1.8.7-2010.01 [ x86_64 ]
Terminal: bash
In this post I’m going to cover how to make a Rails specific gem using jeweler, how to embed a test rails app in the gem, and how to test your gem code with rspec.
I have a gem that I’ve helped build. It’s called Surveyor. We’ve used it on several of our apps here at NUBIC and it’s been working out pretty well.
I’ve never been happy with our test suite. It’s very temperamental. For the longest time it had to run it inside of an app that had been built just for testing and development purposes which is annoying. Also, it is another barrier to having people in the budding Surveyor user group help out, add features, etc, etc… Not having a proper test suite is somewhat irresponsible, time to correct that problem so development can move forward at full speed.
Surveyor now is working fine as a standalone gem and the specs run inside the gem repo and use the Rails app context.
Step 1 - Jeweler
We started using Jeweler for Surveyor some time ago. It seems to work well. We’re going to use it here.
Get Jeweler from Rubygems. Here’s the github page with instructions on how to install the gem. The version I use in this example is version 1.4.0. Follow the instructions in the Readme on the github page or the downloaded gem. Also remember to run jeweler --help to see all the params you can pass in. The gist of the process is:
jeweler [options] <name_of_gem>
For this example I’ll pretend I’m creating a gem to help us have customized Rails log reporting. I’m going to call my gem ‘bclog’ (bc is for bio-computing, though coincidentally ‘bc’ are also my initials). This gem will be tested with cucumber and rspec so I’ve included those options when running the jeweler command. See below:
brian$ jeweler --rspec --cucumber bclog
create .gitignore
create Rakefile
create LICENSE
create README.rdoc
create .document
create lib
create lib/bclog.rb
create spec
create spec/spec_helper.rb
create spec/bclog_spec.rb
create spec/spec.opts
create features
create features/bclog.feature
create features/support
create features/support/env.rb
create features/step_definitions
create features/step_definitions/bclog_steps.rb
Jeweler has prepared your gem in bclog
Great! If you cd into your new gem dir you’ll be able to run $ rake -T and see all the neat things Jeweler can do for you. We won’t be covering any of those tasks here but it’s good to know that Jeweler has a lot of helpful features for your gem development.
Step 2 - Our dev gemset with RVM
Before we get going into modifying our gem we’ll need to set up our development gemset. To do this you’ll need RVM installed. I highly recommend using RVM for development. Even if you don’t have need for multiple ruby versions the ability to easily setup gemsets on a per-directory level is VERY helpful.
I’m assuming you’ve installed RVM, follow these instructions to install RVM if you don’t have it. To create a gemset stand in our new gem directory and run the command below. For more info on RVM Gemsets see this page.
rvm gemset create bclog
We’ll want to have this gemset being used every time we work on this project. Create an .rvmrc file in the project so that everytime you change to this directory the gemset is auto-loaded. One less thing to worry about. Here’s some more information on the RVM site about the workflow.
echo 'rvm_gemset_create_on_use_flag=1; rvm gemset use bclog' > .rvmrc
Now when we cd into the directory we’ll automatically start using this gemset. Give it a try now to make sure it’s working. cd up one dir and back into the project dir. You’ll see a warning message the first time you do this (say ‘yes’ to the message).
Step 3 - Bundler and Gemfile
In the gemset for the gem, install Bundler (1.0.3 as of writing).
Running gem list should show two gems installed; bundler and rake. See below:
brian$ gem list
*** LOCAL GEMS ***
bundler (1.0.3)
rake (0.8.7)
Create a file called Gemfile in your project directory. Load it up with the Gems we need at this point.
source :rubygems
gem 'jeweler'
gem 'rspec', '~> 1.3'
gem 'rspec-rails', '1.3.3'
gem 'cucumber', '~> 0.8.0'
gem 'rails', '2.3.10'
Save this file and then run bundle install
This should install some gems into your local gem bundle.
Step 4 - First gem build and dev setup
Now that your gems are installed (specifically jeweler at this point). Run rake -T to see the Jeweler tasks available to you. What we need to do at this point is setup the gem we’re building so when we include it in our Gemfile as a local, path specific gem, bundler will recognize it as a gem. This means, having a version number and a .gemspec file.
I opened up my Jeweler generated file lib/bclog.rb and added a module definition… it’s for fun at this point. We’ll be adding more to this file later.
module Bclog
# Awesome code goes here...
end
Now run some commands!
brian$ rake version:write
Updated version: 0.0.0
brian$ rake gemspec
Generated: bclog.gemspec
bclog.gemspec is valid.
Pop over to your Gemfile and add the line below. Substituting ‘bclog’ with the name of your gem. This tells bundler to load up the gem your building into the gemset for the project.
plugin_root = File.dirname(__FILE__)
gem 'bclog', :path => plugin_root
Run the install command for bundler
bundle install
Look for your gem in what is printed to the command line. You should see something like this: Using bclog (0.0.0) from source at /Users/brian/bclog
Step 5 - Rake tasks for building test app
Now we are going to create some rake tasks to handle the setting up and tearing down of the test Rails app we’re going to embed in our spec folder. In the Rakefile for this new gem add the following lines from this gist
If you run Rake -T now you should see these new tasks:
rake testbed:build_app # Install rails base app in spec dir
rake testbed:copy_files # Copy in setup files to test app
rake testbed:install_surveyor # Install surveyor in rails base app, runs migrations, preps for testing
rake testbed:remove_app # Remove rails base app in spec dir
rake testbed:setup # Setup for the test app (create)
rake testbed:teardown # Teardown for the test app (remove)
There are a few files you’ll need to put in your gems spec directory. These are files that are specific to your development and bundler environment. There is a rake task called testbed:copy_files that will copy the files from the base of the spec folder to where they should belong inside your test rails app. Here are the files as gists: testboot.rb, testpreinitializer.rb, test_Gemfile
After you have created these files in your spec/ folder in the gem you can run the rake testbed:setup task to install the rails app in your spec folder.
Running this task should put a lot of output to the console, it’s running a Rails generator, installing a bundle, copying files, etc… When it’s done you should see a test_app folder in your spec directory.
Step 6 - Start your testing!!
At this point I’ve covered the basics and you should be ready to start writing and running tests on your gem as you would in a Rails app (ie rake spec, rake features).
Note: For a good overview of Rakefiles and their usage see this blog post by Jason Seifer.
Rails2.3.9,
cucumber,
development,
gems,
rails,
rspec,
testing | in
Programming,
Rails 


