Until recently I considered writing tests for my applications much like reading Dickens in high school: boring, repetitive, hard to understand, and yet for some reason a total necessity. What’s more, I wrote tests about as frequently as I read Dickens – and I’ve never read any Dickens. My meandering point here is that Test Driven Development (TDD) seems to be the standard of the rails community, yet I don’t know a single person who actually does it. With that it mind, I decided to develop our last client’s application with tests written to the best of my ability. At first I thought I was burying my productivity in the minutia of each test, but I ended up learning quite a few things, including the value of testing.
I guess the first thing to do here is to describe my tools. To test with Rails I used RSPEC, Factory Girl, and Capybara.
RSpec is a testing tool for Ruby. Baked into the gem is a rich command line program with detailed error reporting. The beauty of Ruby, and RSpec, is that it enables you to write human readable tests that tell a story. For instance:
it 'has a list of employees' do
employee = Employee.new('John', 'Smith')
company = Company.new([student])
Though testing with RSPEC ensures that our models behave the way we expect, there is a serious problem with this approach: It takes forever. Testing any sort of interesting behavior not only involves extensive amounts of setup to your environment, but a tremendous amount of code to create various instances of your model. This is where Factory Girl comes in. Factory Girl allows a tester to create factories that create multiple records for a model with some generic attributes that are able to be overridden as needed. This means that creating a unique record is as simple as:
FactoryGirl.create(:employee, name: "Jon Snow").
My last tool in my little testing toolkit is Capybara. Where RSpec is a way to test your models, Capybara allows your application to test external behavior. In other words Capybara provides a simple way to test user stories and general behavior. Heres an example:
'When I sign in' do
fill_in 'Login', :with => 'DavidBowie@spidersfrommars.net'
fill_in 'Password', :with => 'whereWereTheSpiders?'
click_link 'Sign in'
So What’s The Point
When I started, I assumed that testing would help to prevent bugs. While this is likely the case, I found that using TDD did something far more valuable. By letting tests to drive the code, developers are forced to conceptualize their application before a single semi-colon is ever written. This forces developers to step through their own logic, which in my case, is full of inconsistencies and little things that I had not thought through fully…likely because I have never read Dickens.