Articles

Software Development Testing in Ruby on Rails

Introduction

In our previous tutorials we have gotten a good headstart in terms of development. Now we will look at the second aspect of our Rails application, testing. Rails beautifully tucks in the unit testing inside the framework. It generates the skeleton code when models and controllers are generated. Rails tests offer one very big benefit over regular tests, they can emulate browser requests and hence, we don't need a browser to test our application's response to the requests.

Setting Up the Test Environment

As Rails applications have a lot of database interaction, it is advised to write tests that check for the constancy of data insertion and retrieval. In order to do so we need to setup a test database and populate it with dummy application data. In this way we can test our application without the data in development and production.

Our database configuration file, database.yml contains a section called test, where we define the name of the test database and connection details. This is how our database.yml file looks:

 

  test:
adapter: mysql
database: eim_test
username: root
password: rails
host: localhost

In order to populate the test database we write fixtures. Fixtures reside in the test folder of application directory.

The tests are of four types : Unit, Functional, Integration and Performance
Click here for larger image

Figure 1

The tests are of four types : Unit, Functional, Integration and Performance.

So let's create our test database and populate it with the test data. First go to MySQL Query browser and create an empty database with the name eim_test.

Go to app_directory/test/fitxtures/employees.yml to edit the users fixtures file. Fixture is a YML file with the name as the name of the table. We need to define the data in a format that corresponds to the columns of the table.

 

  Name Of the Fixture:
Column Name: Value
saurabh:
name: Saurabh
designation: cto
address: mumbai 
Now, run the command:

 

C:eim> rake db:migrate RAILS_ENV="test"
C:eim> rake db:fixtures:load RAILS_ENV="test"

The command line - Rails Testing
Click here for larger image

Figure 2

The command line - Rails Testing
Click here for larger image

Figure 3

Now, we are ready to write unit tests into our application because our test environment is ready.

Unit Test for Our Models

When we created our model or scaffold, a default test is created with it. The employee_test.rb under test/unit looks like this by default

 

  require 'test_helper'
class EmployeeTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end

What it does is take a class, it creates an instance of it, and passes the value inside that instance. It then compares it with the values of it inside the database. So, now we test our employee model as follows:

 

  require File.dirname(__FILE__) + '/../test_helper' 
class EmployeeTest < ActiveSupport::TestCase
def test_initialize
first_employee = Employee.new(:name => 'Sam', :designation => 'ceo',:address => 'california')
assert_equal('Sam',first_employee.name)
assert_equal('ceo',first_employee.designation)
assert_equal('california',first_employee.address)
end
end

We initialize our unit test, create an an instance of the class employee called first employee and pass values inside it. Assert equal, method goes and check the database whether the values have been inserted correctly or not. Once we have written our assertions, we simply go and run the test file just like we do any Ruby program.

 

  C:eimtestunit> ruby employee_test.rb

The dot (.) just above Finished line in the screenshot indicates the test has passed.
Click here for larger image

Figure 4

The dot (.) just above Finished line in the screenshot indicates the test has passed.

In order to test the validations inside the model, we can write a simple test method , which creates an instance of the model class and tries to insert null data. If the test passes, it means the validation is running fine and no data has been insterted.

 

  def test_should_not_save_employee_without_name
employee = Employee.new
assert !employee.save
end

Now the above methods of testing write particular functionality and define how the data should be passed using that. This method is commonly used for what is known as Test Driven Development or TDD. In TDD , first the tests are written with conditions that fail. Then the code is written and tests are made to pass. It is a commonly followed approach. There are however new approaches that have come up in last few years like Behavior Driven Development, which we will look in our later tutorials.

Functional Tests For Controllers

The tests for model, check the insertion and retrieval of the data using our model classes. The controller tests check for the flow of the actions. Which actions? Success of the user request, authentication, redirection, display of messages correctly.

These tests lie inside tests/functional folder. While writing the scaffold we had generated the skeleton tests. Here is how our default index test looks.

 

  class EmployeesControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:employees)
end

Test should get index means the test should go to the index action and make a get request, and makes sure that request gets fulfilled and checks whether a valid post method has been added to the instance variable.

We will customize our tests now.

 

    test "should create employee" do
assert_difference('Employee.count') do
post :create, :employee => {:name => 'John',:designation => 'officer',:address => 'california' }
end
assert_redirected_to employee_path(assigns(:employee))
end

In this test, the test case, first checks for the number of records, then using the create action, sends a post request, with the data inside the instance. Once that is done, it sends the request to redirect it to the appropriate page after the action has been performed.

We can also make use of the fixtures we created earlier in order to perform these tests. Then we can simply call the fixture as an attribute inside the instance and it will pass all the values defined in the fixture automatically. Earlier in this tutorial we created a fixture called saurabh, we will use that fixture to test our show, edit methods.

 

  test "should show employee" do
get :show, :id => employees(:saurabh).to_param
assert_response :success
end
test "should get edit" do
get :edit, :id => employees(:saurabh).to_param
assert_response :success
end

The types of requests handled by these tests are get, post, put, head, delete, which are http requests in general. Apart from the requests, once the request has been fulfilled, hash objects will be generated and they would be available at the disposal of the tests to use.

  • Assigns - They are objects assigned for use inside the views and contain instance variables.
  • Cookies - Any available cookies for the application
  • Flash - Any Flash objects, which means Flash method to display messages inside rails.
  • Session - All the stuff that lives inside session variables.

Conclusion

We have looked at how we can check the application flow and the data insertion inside our rails application. We have seen how are tests work and written some basic tests. There are however several kinds of assertions available in the Rails testing framework, which can be checked on the Rails API.

In the coming tutorial we will look at testing the views, integration tests, and the basics of Behavior Driven Development.

Original Story


Website Design | Website Development | Flash animation | Flex applications | Logo Design | Mobile Applications Development | iPhone | iPad | Google Android

Content Management Systems | E-Commerce | Social Networking | Dating Websites | Membership Websites | Zend Framework | PRADO | Symfony | Wordpress

ASP.NET | PHP | C# | Objective-C | AJAX | Web 2.0 | HTML | CSS | Javascript | MySQL | MSSQL

 


Host unlimited domains + get up to 5 FREE domains with your 1&1 hosting account. Must see monthly hosting specials!


Invite your friends to Stable Flow

Enter up to 3 email addresses of your friends: