---
title: Shhh! Your Test::Unit backtraces are too noisy!
teaser: Noisy backtraces make problems hard to spot.
tags: news,web,ruby,testing
author: Dan Croak
published_on: 2007-12-03
---

For more details on the history of this little open source effort, see James
Golick's post at [James on Software].

[James on Software]: http://jamesgolick.com/2007/12/1/noisy-backtraces-got-you-down.html

I'm a child of the Information Age, over-stimulated with a tiny attention spa
&hellip; hey, a blue car!

Therefore, I love Rails and Agile processes for focusing my mind so I don't get
distrac&hellip;haha, those squirrels are chasing each other! I'll call the
little one Bitey.

However, `Test::Unit` backtraces are too noisy for my tastes. Most of this
typical backtrace will not help me fix the code:

    1) Failure:
    test: logged in on get to index should only show projects for the user's account. (ProjectsControllerTest)
    [/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/assertions.rb:48:in &#96;assert_block'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/assertions.rb:500:in &#96;_wrap_assertion'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/assertions.rb:46:in &#96;assert_block'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/assertions.rb:63:in &#96;assert'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/assertions.rb:495:in &#96;_wrap_assertion'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/assertions.rb:61:in &#96;assert'
    test/functional/projects_controller_test.rb:31:in &#96;__bind_1196527660_342195'
    /Users/james/Documents/railsApps/projects/vendor/plugins/shoulda/lib/shoulda/context.rb:98:in &#96;call'
    /Users/james/Documents/railsApps/projects/vendor/plugins/shoulda/lib/shoulda/context.rb:98:in &#96;test: logged in on get to index should only show projects for the user's account. '
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testcase.rb:78:in &#96;__send__'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testcase.rb:78:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testsuite.rb:34:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testsuite.rb:33:in &#96;each'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testsuite.rb:33:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testsuite.rb:34:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testsuite.rb:33:in &#96;each'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/testsuite.rb:33:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in &#96;run_suite'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:67:in &#96;start_mediator'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:41:in &#96;start'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb:29:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/autorunner.rb:216:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit/autorunner.rb:12:in &#96;run'
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/test/unit.rb:278
    test/functional/projects_controller_test.rb:36]:
    one or more projects shown does not belong to the current user's account.
    false is not true.

Noisy backtraces must be ruthlessly silenced.

So, at the inaugural Boston.rb hackfest, we scratched our itch, with especially
good direction from Joe Ferris. As the week progressed, [James
Golick](http://jamesgolick.com/) and I polished the resulting code into a gem
which I am pleased to announce... now.

## Quiet Backtrace

Install the gem:

<kbd>gem install quietbacktrace</kbd>

Run your Test::Unit tests:

<pre>
<samp>1) Failure:
  test: logged in on get to index should only show projects for the user's
    account. (ProjectsControllerTest)
  [test/functional/projects_controller_test.rb:31
  vendor/plugins/shoulda/lib/shoulda/context.rb:98
  vendor/plugins/shoulda/lib/shoulda/context.rb:98
  test/functional/projects_controller_test.rb:36]:
  one or more projects shown does not belong to the current user's account.
  false is not true.</samp>
</pre>

Ooh la la! However, those Shoulda-related lines are cluttering an otherwise
perfect backtrace. Luckily, Quiet Backtrace is designed to be extended by
calling two types of blocks that yield one line of the backtrace at a time.

## Silencers and filters

* Silencers let you specify conditions that, if true, will remove the line from
  the backtrace.
* Filters let you use Ruby's succulent set of
  [String](http://www.ruby-doc.org/core/classes/String.html) methods to modify a
  line by slicing and stripping and chomping away at anything you deem ugly and
  unnecessary. (such as the ":in \_\_bind\_1196527660\_342195" in the original
  example)

Say you want to remove Shoulda-related lines... you create a new silencer and
add it the array of `backtrace_silencers`:

```ruby
class Test::Unit::TestCase
  self.new_backtrace_silencer :shoulda do |line|
    line.include? 'vendor/plugins/shoulda'
  end

  self.backtrace_silencers << :shoulda
end
```

Re-run your tests and bask in the sweet sounds of silence:

<pre>
<samp>1) Failure:
  test: logged in on get to index should only show projects for the user's
    account. (ProjectsControllerTest)
  [test/functional/projects_controller_test.rb:31
  test/functional/projects_controller_test.rb:36]:
  one or more projects shown does not belong to the current user's account.
  false is not true.</samp>
</pre>

Exquisitely sparse. Quiet Backtrace clears distractions from the getting to
green <abbr title="Test Driven Development">TDD</abbr> process like a Buddhist
monk keeping his mind clear during meditation.

## Getting Noisy Again

On occasion, you'll want to see the noisy backtrace. Easy:

```ruby
class Test::Unit::TestCase
  self.quiet_backtrace = false
end
```

You can set `Test::Unit::TestCase.quiet_backtrace` to true or false at any level
in your `Test::Unit` code. Stick it in your `test_helper.rb` file or get noisy
in an individual file or test. More flex than a rubber band.

## Using Quiet Backtrace with Rails

After you have installed the gem, open the `config/environments/test.rb` file
from within your Rails project and add:

```ruby
require 'quietbacktrace'
```

Quiet Backtrace will now work with your tests, but because this gem is meant to
work on any Ruby project with Test::Unit, it does not turn any Rails-specific
silencers or filters on by default. However, there is one of each, ready to be
switched on, that remove the most dastardly lines.

Add these lines to your `test/test_helper.rb` file to get perfectly clean Rails
backtraces:

```ruby
class Test::Unit::TestCase
  self.backtrace_silencers << :rails_vendor
  self.backtrace_filters   << :rails_root
end
```

## Ongoing development

Update: this project was released in the days of Rubyforge and pre-GitHub. The
post has been updated with the libraries' current locations.

The most up-to-date information will always be at [Quiet Backtrace GitHub
project](https://github.com/thoughtbot/quietbacktrace) page.

On a related note, the Boston.rb hackfest (part deux) will be held on December
11 at thoughtbot's office. Any Rubyists in town that night are welcome.
