Importance of Unit Tests

If you are new to writing Rails applications, as I am, you may wonder about the importance of writing tests, especially if everything works as expected in the browser. If so, try this very simple example that demonstrates the importance of testing the model with unit tests.

Create an application folder

>rails testing

Create a model, note* specify words to be a text string

testing>ruby script/generate model Display words:string

Edit the model file, \app\models\display.rb, to ensure that words exists

validates_presence_of :words

Create the table

testing>rake db:migrate

Populate the table with an entry

testing>ruby script/console
>>Display.create(:words => 'test text string')

Create a controller

testing>ruby script/generate controller Displays index

Edit the controller file, \app\controllers\displays_controller.rb

def index
@display_text = Display.find(:all)

respond_to do |format|
format.html # index.html.erb
end
end

Edit the view file, \app\views\displays\index.html.erb

<h1>Displays#index</h1>
<% @display_text.each do |d| %>
<p>
<%= d.words %>
</p>
<% end %>

Verify that everything is working so far.

testing>ruby script/server

Open your browser to http://localhost:3000/displays and you should see

Displays#index
test text string

Edit the unit test file, \test\unit\display_test.rb It should accept a text string entry, should have some text, and not be a numeric entry.

def test_should_create_entry
entry1 = Display.create(:words => 'more test text')
assert entry1.valid?
end

def test_words_should_not_be_nil
entry2 = Display.create(:words => nil)
assert entry2.errors.on(:words)
end

def test_words_should_not_be_empty
entry3 = Display.create(:words => '')
assert entry3.errors.on(:words)
end

def test_words_should_not_be_numeric
entry4 = Display.create(:words => 123)
assert entry4.errors.on(:words)
end

Edit the functional test file, \test\functional\displays_controller_test.rb

def test_should_show_index
get :index
assert_response :success
assert_template 'index'
assert_not_nil assigns(:display_text)
end


# :count is from fixtures file
# test\fixtures\displays.yml
def test_should_show_entries
get :index
assert_select 'p', :count => 2
end

Verify that the tests pass

testing>rake test

You should see

1) Failure:
test_words_should_not_be_numeric(DisplayTest)
......
<nil> is not true.
4 tests, 4 assertions, 1 failures, 0 errors
......
2 tests, 5 assertions, 0 failures, 0 errors

Populate the table with a numeric entry

testing>ruby script/console
>>Display.create(:words => 456)
=> #<Display id: 2, words: 456, created_at: ......>

So what's going on? When the Display model was generated words was specified as a string, and the db\migrate\###_create_displays.rb file has this in it.

def self.up
create_table :displays do |t|
t.string :words

t.timestamps
end
end

check in the browser again.

testing>ruby script/server

Open your browser to http://localhost:3000/displays
There they are

Displays#index
test text string

456

Edit the model file again, \app\models\display.rb, using a simple regular expression to check for the presence of at least one text character.

validates_format_of :words,
:with => /[a-z]+/i

Run the tests again.

testing>rake test

This experience with this very simple application has convinced me of the importance of writing tests. I hope it has convinced you too.

One Trackback

  1. By the Mittineague Blog -> Importance of good Models on September 14, 2008 at 1:32 am

    [...] If you aren't entirely convinced about the importance of using Unit tests to test your Models after trying the steps found in the Importance of Unit Tests post, try these changes that continue on that example. [...]

Post a Comment

Your email is never shared. Required fields are marked *

*
*