Entries in development (2)

Sunday
Nov142010

Testing your Rails 2.3.9 Gem plugin with rspec

Environment Notes:
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.

Thursday
Mar262009

Jumping ship. Moving from Textmate to Vim for Rails development

Background

For the last two years or so I’ve been using Texmate for almost all of my Rails development. When I first started with Rails it was the recommended editor to use and much cheaper than the alternative (BBEdit). I purchased my copy and started hacking away. Even though Textmate met most of my needs I experimented with RadRails (now Aptana), Komodo, and Textpad (on Windows) and none of them had the simplicity, flexibility, or ease of use as Textmate. Recently I’ve noticed that there has been a fall off in Textmate development (version 1.5.8 was release sometime in February, prior to that version 1.5.7 was released in October of 2007!). Not that this is a huge problem, but with the textmate feature request as long as it is I would hope that the developer would be more on top of things.

Why the switch?

After much consideration, I decided to give Vim a try. Part of my reason for a switch in text editors was because I was looking for what would be the the “samurai sword” for software development (if there is such a thing). The other part of the reason why I started looking for other text editors was the ability to open two files at once. While this may not seem like a big deal to most people, I am tired of cmd-T’ing between my models and my spec files, my css and my views, my models and my migrations, etc… Perhaps it’s my development style or lack of short term memory but having to toggle between two files was beginning to wear on me and my productivity.

Why Vim?

Well, it helps that a developer I work with is a Vim guru. Also, (on his recommendation) I started using a Firefox plugin called Vimperator. This is a cool tool that is like a Vim gateway drug. It removes almost all interface elements in your browser and allows you to interact with web pages like they were files in Vim. It’s totally sweet. Being able to browse the web without your mouse is more awesome than you can imagine!

After using Vimperator for a while I started to become comfortable with how to use Vim. I had learned some of the commands to navigate. I was ready to make the plunge into Rails development in Vim.

How to do it

I’m not going to get into how to use Vim. There are far better sites out there for that purpose. Here are some of the add-ons for Vim I recommend to make the transition from Textmate to Vim easier.

  1. First, I use a Mac so MacVim is a must. You can get MacVim here.

  2. Once you’ve got that installed get the Rails script utility to make your Vim Rails aware. It will make it easy to switch between related files, run rake tasks, etc…

  3. To get the nice tree project gutter that Textmate has there is NERDTree. Using the same commands for navigating vim you can navigate your project files with ease.

One last tip… Vim (and other advanced text editors) have a lot of sharp edges. One which cut me was the caps lock key. Caps lock is a pretty useless key. I’m not sure how it ended up on modern computers. Perhaps so people can unleash the fury?! Anyway, there is this neat program called PCKeyboardHack that will allow you to remap your caps lock key to esc which is great for Vim because the esc key is vital to Vim usage.

The old (and busted)

The new (with teh hotness)

Hope this post helps with your Textmate to Vim conversion. It takes sometime to make the transition but it’s worth it. I’ll post more tips when I have them.