Finished in 11.541093 seconds.
3001 tests, 5325 assertions, 0 failures, 0 errors
I gave a lightning talk on testing at the Ruby Hoedown conference last weekend. Emphasizing the need for a test suite to run quickly, I ran through how my ThoughtWorks team tests differently than the basic Rails setup. The metric above is from our unit test suite. An important note is that I'm not using the term "unit test" the same way Rails does. We unit test our models without hitting the database. We also unit test our controllers, testing them without rendering the view and with mocking the models.
To run tests without hitting the database, my team was using this code from Muness Alrubaie, based on the original implementation from Jay Fields. Big props and thanks to Jay for his work on this - disconnecting unit tests from the database is a huge time saver and productivity gain for a development team. Other people have made their own variations.
However, this implementation has few weaknesses:
While moving through iterations of improvements to prevent these issues, we had to fix quite a few tests. All of them were doing something that would not work if it wasn't for the "specialized" constructor. We ended up developing a much better solution: we determine columns from the schema.rb file. This enables us to have really fast unit tests that do not hit the database, while solving the problems outlined above of having slightly different behavior. Each model has the columns defined exactly as in the actual database.
I wrapped the new and improved approach into a gem called "UnitRecord." This naming may be confusing since Rails refers to unit tests as any model test. However, when testing your application's business logic, you should do just that. Testing the ActiveRecord framework in addition to your business logic is unnecessary - ActiveRecord has its own suite of tests. Therefore, disconnecting from the database allows you to test the business logic in isolation from the persistence logic and have really fast tests.
gem install unit_record
Using the gem involves a few steps covered in the documentation.
Jay Fields wrote a blog entry on how we test. UnitRecord is one piece of the picture. We also use a factory instead of fixtures, and define tests using dust.
If you're using autotest, restrcturing your test directory to support UnitRecord will break autotest. Jamie Hill wrote a plugin to autoest with unitrecord
Geoffrey Grosenbach wrote a rake task to convert the Rails test directory structure. Subversion commits are built-in, so you may want to try it out on a branch or look closely before running it.