Don't settle for 99%

August 07, 2012

The goal for unit testing is 100% test coverage, but most developers will tell you that not everything will be able to be tested. Most programmers settle for 99% coverage. Don’t do that.

There is no good enough when it comes to unit testing. Every line of code of your program should be executed at least once. Lets take a look at an example of code that is normally not tested.

def get_move_from_user
  cords = @io.gets.chomp

  raise IllegalMove.new("Bad input") unless cards =~ /^\d+$/

  cords
rescue IllegalMove => error
  display_text "Illegal Move: #{error.message}. Please try again"
  retry
end

This example shows a rescue block with a retry. This is hard to test, as there is no good way to make sure that the exception was raised. Instead of skipping those two lines, we can create a IOMock object that takes an array of input to return one at a time.

class IOMock
  def initialize(input)
    @input = Array(input)
  end

  def gets
    @input.pop
  end
end

This now allows us to pass in multiple inputs, the first failing and the second succeeding.

def test_get_move_from_user
  mover = Mover.new( IOMock.new(['1', 'a']) )
  assert_equal '1', mover.get_move_from_user
end

Suddenly we’re two lines closer to 100%.

Don’t settle. There is almost always a way to get 100%, and if not, you may be doing something wrong.


Profile picture

Written by Eric Koslow a programmer with too much time on his hands You should follow them on Twitter