MiniTest ProgressBar

I was recently inspired by a blog post I read about a new Ruby gem called Fuubar.  The premise of this gem is to have your RSpec tests instafail, giving an immediate backtrace when a test fails or errors; that way you don’t have to wait for all of your tests to complete before researching a problem.  It also makes use of one of my favorite gems, ProgressBar, to replace that boring standard test output of periods and letters with a progress bar.  To top it off, the output color shifts as your tests fail/error (red) or are skipped (yellow), or remains green if they all pass.  I find this test reporting to be much more informative and useful, but unfortunately we don’t use RSpec (actually it was written on RSpec 2), so if I wanted this I was going to have to come up with my own solution.

We’ve actually only recently started really trying to integrate testing into our projects, and we’ve chosen to use MiniTest.  After upgrading to the latest version (2.0.0), I had high hopes that I could just mimic the behavior of the Pride extension, replace the default MiniTest::Unit.output with my own MiniTest::ProgressBar object that would convert the lovely periods and letters into the colored progress bar I longed for.  Unfortunately I quickly discovered that MiniTest doesn’t expose any of the import things I needed, like a total count of tests being run.  

I decided to start with a proof-of-concept (read: dirty override hack) just to be sure I could get the output I wanted from MiniTest.  What I ended up with looked something like this:

Like I said, it’s dirty, but it works.  What I’m left with now is an output from running my tests that looks like this:

I feel satisfied with the output.  I have a colorful progress bar as well as instafailing for efficient bug stomping.

All of this work was done in our project as a monkey-patch, but I’ve decided to try and clean this up.  So I’ve forked SeattleRB’s MiniTest on my GitHub account, and am currently working to make this change a little cleaner.  My intention is to make the test reporting more pluggable using an event system with events being raised upon completion of individual tests, test suites, and the entire test run, that a plugin can then hook into and report in a custom manner.  As I progress further, I’ll update here with how things turn out.