---
title: 'Internbot Chronicles #3'
teaser:
tags: playbook,apprenticeship
author: Nick Quaranto
published_on: 2009-04-24
---

Now that testing is a normal part of my daily workflow, I think it's a great
time to go over some of the testing tools that I use here at thoughtbot.

## Shoulda

Typing too much makes testing no fun at all. I'm actually coming from the RSpec
world, and thankfully it was pretty easy to switch over to
[Shoulda](http://github.com/thoughtbot/shoulda/tree/master) from it. Here's what
I like best about it:

[![''](http://farm3.static.flickr.com/2159/2232153944_d376d5a2f2_m.jpg)](http://www.flickr.com/photos/mundane_joy/2232153944/)

* `context` and `setup` blocks makes testing ridiculously simple and <abbr
  title="Don't Repeat Yourself">DRY</abbr>.
* `before_should`: Basically, you can set up expectations with your favorite
  mocking framework in these blocks, which run before the `setup` block in the
  given `context`.
* Macros that just save tons of time. Simple ones like `should_redirect_to` are
  actions that need to be tested all the time, and luckily there's a whole suite
  of them for both
  [ActiveRecord](http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActiveRecord/Macros.html)
  and
  [ActionController](http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActionController/Macros.html).
* Custom macros that can be easily dropped in to test the same actions in
  multiple places. I do miss RSpec's `it_should_behave_like` though, but this
  works decently.

## Mocha

The concept of mocking and stubbing in general is somewhat new to me, and it's
definitely been difficult to learn how to use effectively. It's starting to
become natural though, and I don't mind the speedup that testing in isolation
gives. The majority of our projects use [Mocha](http://mocha.rubyforge.org),
which does the job just fine. I've also been looking into
[RR](http://github.com/btakita/rr/tree/master), which has a [much cleaner syntax
and some additional
features](http://technicalpickles.com/posts/ruby-stubbing-and-mocking-with-rr/),
but usually my daily mocking is done with Mocha. The most important thing for me
to remember is to avoid situations where test pass but the code is broken due to
excessive stubbing of behavior. The sweet spot with this is to use integration
testing to cover all the bases.

## factory_bot

If you've ever dealt with the frustration that is Rails fixtures, then you know
the [breath of relief that
factories](http://github.com/thoughtbot/factory_bot/tree/master) can give your
tests. Being able to generate new models with a simple `Factory(:post)` call
makes testing ridiculously easy. Some of the latest features I've been using is
the `:parent` option on `Factory.define`, which allows you inherit attributes
from another factory. [Clearance has a great example of
this](http://github.com/thoughtbot/clearance/blob/master/generators/clearance/templates/factories.rb)
in how it creates a `Factory(:email_confirmed_user)` that descends from
`Factory(:user)`.

## Cucumber

I've learned about user stories in classes, but being able to write them in
plain English and run them with Ruby has totally blown me away. Outside-in
development is a great way to approach features that need to be built and tested
from the ground up. [Ben Mabey's presentation at MountainWest
RubyConf](http://mwrc2009.confreaks.com/14-mar-2009-15-00-bdd-with-cucumber-ben-mabey.html)
has a great example of how this development method works if you haven't tried it
out yet. The best part I find is that it can be read by clients or developers
coming into the project, and it can be used outside of the Rails environment as
well. Take some time and look into Cucumber if you haven't already, and [start
at their fantastic site](http://cukes.info).

## FakeWeb

Mocking out external <abbr title="HyperText Transfer Protocol">HTTP</abbr> calls
is difficult. If you're working with any sort of <abbr title="Application
Programming Interface">API</abbr> from another site and you want to ensure that
your code is actually submitting to it, relying on
[FakeWeb](http://fakeweb.rubyforge.org) is a good choice. The syntax and setup
is really simple, and it will usually look something like this:

    require 'fake_web'
    FakeWeb.allow_net_connect = false
    FakeWeb.register_uri(:post, "http://somesite.com",
      :string => 'response body')

This little snippet will cause FakeWeb to throw errors if any other <abbr
title="HyperText Transfer Protocol">HTTP</abbr> calls are made outside of the
ones registered. The final line will tell the library to return the given string
when that <abbr title="Uniform Resource Locator">URL</abbr> is hit from the
application with a POST request. Like most projects in the Ruby world, it just
works.

## Testing in your shell

[![''](http://farm3.static.flickr.com/2054/2553559302_10afed54bf_m.jpg)](http://www.flickr.com/photos/sha_junglii/2553559302)

Being a [convert to vim from
TextMate](https://thoughtbot.com/blog/integrating-vim-into-your-life), running
tests usually isn't as simple as doing Cmd+R. Luckily there's two tools that
help out with this. One is [autotest](http://zentest.rubyforge.org/ZenTest/),
which I'll run if the test suite for the app I'm working with doesn't take too
long. What I love best is that it fires off the test immediately after a `:w` in
vim, so I don't have to do any sort of context switching to run the test. It can
get annoying though, and modifying your `~/.autotest` to [not run the entire
suite after fixing a failed test](http://gist.github.com/98663) helps cut that
down. Another helpful thing that some of the thoughtbotters use is a [zsh script
that adds autocompletion](http://gist.github.com/101130) for running unit and
functional tests. Basically just type `tu` or `tf`, and tab away.

If you know of other testing tools that we should be looking into, speak up in
the comments!
