Unit Testing in Rails

Neelkanth Ram

2 min read

Before I jump in to saying how to write unit testing in Ruby on Rails, let me share what i felt about testing. When I was introduced about Unit Testing, I felt its simply a waste of time (IMHO I think many coders before getting addicted to testing might feel the same way), what is so great about testing if I can test my own code manually that’s what coders (people who are not aware of unit testing importance) might think so.
Initially I wasn’t writing any test cases and I started adding more and more features to my application. My application became big and I wasn’t able to test every pieces of my features manually. I made a minor change and it started breaking other few features, but I didn’t realize it until my colleague spotted it. It was easy to fix so I fixed but, some times it takes hours to fix a bug, bugs are invisible and invincible if you don’t write testcases, I made an innocent change over here, but it broke stuff way over somewhere, I am afraid to refactor or change my code now. So the moral of the stroy is “write test cases“.
Writing test cases is like drinking beer, it tastes bitter if you are new to it but it tastes great after your taste buds realizes it. Eventually you will get addicted to it. 😉 Many developers who realized the importance of testing became addicted to testing. They start writing code only when they had beer oops sorry I mean writing tests first.
Writing test cases in Ruby on Rails is as simple as shown below
[source language=”Ruby”]
class FirstTest < ActiveSupport::TestCase def test_addition assert(1 + 1 == 2, "Addition should work.") end def test_subtraction assert(2 - 1 == 2) # should fail end end [/source] If you are using Netbeans, you can use short cut keys like shift+F6 or Ctrl + F6 to run the test. Now, lets create a simple model in Rails, say Account (item:string, amount:decimal)
Account.rb
[source language=”Ruby”]
class Account < ActiveRecord::Base validates_presence_of :item validates_numericality_of :amount end [/source] Now the test case for the about model would look something like below code. Please see the inline comments for more info about the below test case. account_test.rb
[source language=”Ruby”]
require ‘test_helper’
class AccountTest < ActiveSupport::TestCase #loads fixtures from accounts.yml fixtures :accounts def test_should_create_account assert_difference 'Account.count' do account = create_account assert !account.new_record?, "#{account.errors.full_messages.to_sentence}" end end def test_should_require_account_item assert_no_difference 'Account.count' do account = create_account(:item => nil)
assert account.errors.on(:item)
end
end
def test_should_require_account_amount_numeric
assert_no_difference ‘Account.count’ do
account = create_account(:amount => ‘foo’)
assert account.errors.on(:amount)
end
end
#The below protected method creates an account record in the test database mentioned in database.yml
protected
def create_account(options = {})
record = Account.new({ :item => ‘Mouse’, :amount => 25.05 }.merge(options))
record.save
record
end
end
[/source]
Now lets see how the results would look like if I run the test case via Netbeans IDE.
testresults
BTW, there is limit on number of beers that one can drink and so number of test cases one can possibly write. I will soon write a blog about it with the help of some test coverage tools like rcov. I would be interested in hearing your comments as well.

Related posts:

2 Replies to “Unit Testing in Rails”

  1. I can’t agree more with your points on testing… I really didn’t understand how important they are until I started doing TDD. TDD has made me a better and faster programmer. Tests are VERY important.
    My friend posted a really good blog post that made it very clear though a real-world analogy. http://app.arat.us/blog/?p=159

Leave a Reply

Your email address will not be published. Required fields are marked *