Ruby Unit Testing

by woody2shoes on January 22, 2009

I’ve been working on NORM and after a few proof of concept things, I wrote a test to test the create method for the base class.

Here’s the create method:

def create(attributes)
  columns = attributes.keys.join(", ")
  values = attributes.collect {|k, v| "'#{v}'"}.join(", ")
  @@connection.execute("INSERT INTO base (#{columns}) VALUES (#{values});")
  new(attributes)
end

I’ve written dozens of unit tests in Ruby on Rails, but what I didn’t realize was that the same library you use to test in Rails is the standard test/unit library came with the Ruby installation on my Windows machine. So, I wrote my own test which I later revised.

Original test:

require "base"

def test_create
  dbh = DBI.connect("DBI:Mysql:norm:localhost", "root", "")
  dbh.execute("DELETE FROM base;")
  Base.create(:name => "dope", :address => "dopes house")
  if dbh.select_one("SELECT COUNT(*) as count FROM base WHERE name = 'dope' AND address = 'dopes house';")[0].to_i != 1
    puts "test failed"
  end
end

test_create

Revised Test:

require "test/unit"
require "../base"

class BaseTest < Test::Unit::TestCase
  def test_create
    dbh = DBI.connect("DBI:Mysql:norm:localhost", "root", "")
    dbh.execute("DELETE FROM base;")
    Base.create(:name => "dope", :address => "dopes house")
    assert_equal dbh.select_one("SELECT COUNT(*) as count FROM base WHERE name = 'dope' AND address = 'dopes house';")[0].to_i, 1, "Object not created"
  end
end

I fully intend to write methods in the Base class that replace the DBI calls in my tests, but right now I don’t have anything else tested that I can use.

It turns out that testing in Ruby is extremely easy. It’s not just a nicety that you inherit when you start using the rails framework. You simply include the unit/test library with a require statement:

require 'unit/test'

Then all you do is create a new class and inherit the Test::Unit::Testcase class:

class YourClassTest < Test::Unit::Testcase

Any method you define that has a name beginning with test_ will be executed. You can find the assertions list and how to use them at http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/. You can also find a good powerpoint on testing and test driven development at http://www.cis.upenn.edu/~matuszek/cit597-2008/Lectures/35-unit-testing-in-ruby.ppt.

Enjoy and good luck!

Previous post:

Next post: