CSC/ECE 517 Fall 2011/ch4 4e gs: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
<h2>Lecture 10 - Testing in Rails</h2>
<h2>Lecture 10 - Testing in Rails</h2>
__TOC__
__TOC__
== Introduction ==
==Introduction==
This article covers testing in rails which is the content of Lecture 10.
This article is a summary of Lecture 10 "Testing in Rails" and it basically describes in detail the various types of tests in rails one encounters while developing a typical rails app. There are four components central to testing in rails: Fixtures, Unit tests, Functional Tests, Integration Tests and Performance tests. These have been describes below.
There are four components central to testing in rails: Fixtures, Unit tests, Functional Tests, Integration Tests and Performance tests.


==Fixtures==
==Fixtures==
==Unit Tests==
==Functional Tests==
Fundamentally, these tests are used for testing the 'functionality' of the various components of a controller. So typically, one has as many functional tests as there are controllers. The basic purpose of writing functional tests is to check if methods of a controller are working correctly. Since controllers often influence the content of the web page (which is rendered by the corresponding method of a controller) functional tests are typically written to check if the controller’s method is rendering/redirecting to the correct page, that users are getting authenticated correctly, that the content displayed on the page is correct etc. Functional tests are also used to test the View because controllers and views are tightly coupled in rails. This tight coupling is evident by the fact that instance variables in the controller are available to the view. Hence, view related functionality can also be tested in functional tests e.g. the most common kind of view test would be checking that the title of a web page is  displayed correctly.
An example of a functional test:
<pre>
test “should use layout” do
get :index
assert_response :success
assert_select ‘title’, ‘Online Cookbook’
end
</pre>
In rails the title of the test gives you a absic idea of what the test does. In this case,  "should use layout" implies that this test checks the layout of the page. The gist of this test is that it GET's the index page (corresponding to view of this controller), ensures that the page is rendered correctly with the mothod: <pre> assert_response </pre>Finally it checks that the title of the page is "Online CookBook". <pre> assert_select </pre> This method allows you to select the value of a particular tag from html - in this case the title tag.
==Integration Tests==
Typically in software development, different modules of a project are worked on by different teams/developers. Each team might ensure that the model works correctly in-itself, but this might not necessarily be the case when all the modules are coupled together as a single unit. This is where Integration tests come into play. They test the interaction between multiple controllers and all the components in a sequence, end-to-end. An example would be that of a shopping cart application. Even though different phases of the application may work correctly while integration testing one might realize that the 'add to cart' button is absent in the product-catalog although the add to cart functionality has been correctly implemented.
The default integration tests framework included in Test-Unit are very low level i.e. they deal with HTTP GET, POST requests responses, session objects, cookies, redirects etc. In ''Behavioral-Driven-Development'' we want to deal with the system on a higher level – similar to a user’s interaction with the system i.e. we want to deal only with clicks, with typing etc. Hence, we can use some of the popular Integration Testing frameworks like Capybara which is a GUI testing framework and allows one to specify - within a test - various actions like 'click' to click on a button, 'fill_in' to fill some text into a designated text-box etc. We can see that this is at a high level and somewhat analogous to actions an end-user might go through while using the application. So the rule of thumb while writing integration tests is to identify the end-users requirements and scope of interaction with the system, walk through the steps that they would take and mimic those in the form of tests. It is clearly evident how such ''Behavioral-Driven-Development'' goes hand in hand with ''Test-Driven-Development'' and helps in removing the ambiguities often associated with Customer Requirements.
An Example:
<pre>
test “create category from main page” do
visit categories_path
click_link “New category”
fill_in “category_name”, :with => “Sample Category”
click_button “Create Category”
end
</pre>
Here we have simulated a user-action (for the CookBook example) where the user would carry out the following steps:
# Visit the Categories Home Page (whose url is specified as categories_path by the routes.rb file)
# Click on the Link which says "New Category", which would lead to another page.
# On this new page, fill the text-box with some text, say "Sample Category"
# Click on the button that says  "Create Category".
One can easily identify these actions from the code which is highly intuitive and self-explanatory. Capybara thus provides us with these convenient methods which greatly expedite the whole Integration Testing process.
To use the framework, simply include the corresponding gem in the Gemfile, and the following lines to the end of the ''test_helper.rb'' file.
<pre>
# Add more helper methods ...
require ‘capybara/rails’
class ActionDispatch::IntegrationTest
include Capybara::DSL
end
</pre>
The easy-to-use commands mentioned before are created by Capybara using a Domain Specific Language (DSL) and in order to be able to use it, every Integration written must ''require 'test_helper' ''. This is basically a ''mixin'', so one still has the capability to access all the low-level GET/POST commands in Test-Unit.
In sum, Integration tests are vital and are carried out in the final stages of testing to ensure that the system works as a cohesive and complete unit.
==Performance Tests==
==Conclusion==

Revision as of 05:44, 20 October 2011

Lecture 10 - Testing in Rails

Introduction

This article is a summary of Lecture 10 "Testing in Rails" and it basically describes in detail the various types of tests in rails one encounters while developing a typical rails app. There are four components central to testing in rails: Fixtures, Unit tests, Functional Tests, Integration Tests and Performance tests. These have been describes below.

Fixtures

Unit Tests

Functional Tests

Fundamentally, these tests are used for testing the 'functionality' of the various components of a controller. So typically, one has as many functional tests as there are controllers. The basic purpose of writing functional tests is to check if methods of a controller are working correctly. Since controllers often influence the content of the web page (which is rendered by the corresponding method of a controller) functional tests are typically written to check if the controller’s method is rendering/redirecting to the correct page, that users are getting authenticated correctly, that the content displayed on the page is correct etc. Functional tests are also used to test the View because controllers and views are tightly coupled in rails. This tight coupling is evident by the fact that instance variables in the controller are available to the view. Hence, view related functionality can also be tested in functional tests e.g. the most common kind of view test would be checking that the title of a web page is displayed correctly.

An example of a functional test:

test “should use layout” do
	get :index
	assert_response :success
	assert_select ‘title’, ‘Online Cookbook’
end

In rails the title of the test gives you a absic idea of what the test does. In this case, "should use layout" implies that this test checks the layout of the page. The gist of this test is that it GET's the index page (corresponding to view of this controller), ensures that the page is rendered correctly with the mothod:

 assert_response 

Finally it checks that the title of the page is "Online CookBook".

 assert_select 

This method allows you to select the value of a particular tag from html - in this case the title tag.

Integration Tests

Typically in software development, different modules of a project are worked on by different teams/developers. Each team might ensure that the model works correctly in-itself, but this might not necessarily be the case when all the modules are coupled together as a single unit. This is where Integration tests come into play. They test the interaction between multiple controllers and all the components in a sequence, end-to-end. An example would be that of a shopping cart application. Even though different phases of the application may work correctly while integration testing one might realize that the 'add to cart' button is absent in the product-catalog although the add to cart functionality has been correctly implemented.


The default integration tests framework included in Test-Unit are very low level i.e. they deal with HTTP GET, POST requests responses, session objects, cookies, redirects etc. In Behavioral-Driven-Development we want to deal with the system on a higher level – similar to a user’s interaction with the system i.e. we want to deal only with clicks, with typing etc. Hence, we can use some of the popular Integration Testing frameworks like Capybara which is a GUI testing framework and allows one to specify - within a test - various actions like 'click' to click on a button, 'fill_in' to fill some text into a designated text-box etc. We can see that this is at a high level and somewhat analogous to actions an end-user might go through while using the application. So the rule of thumb while writing integration tests is to identify the end-users requirements and scope of interaction with the system, walk through the steps that they would take and mimic those in the form of tests. It is clearly evident how such Behavioral-Driven-Development goes hand in hand with Test-Driven-Development and helps in removing the ambiguities often associated with Customer Requirements.

An Example:

test “create category from main page” do
	visit categories_path
	click_link “New category”
	fill_in “category_name”, :with => “Sample Category”
	click_button “Create Category”
end

Here we have simulated a user-action (for the CookBook example) where the user would carry out the following steps:

  1. Visit the Categories Home Page (whose url is specified as categories_path by the routes.rb file)
  2. Click on the Link which says "New Category", which would lead to another page.
  3. On this new page, fill the text-box with some text, say "Sample Category"
  4. Click on the button that says "Create Category".

One can easily identify these actions from the code which is highly intuitive and self-explanatory. Capybara thus provides us with these convenient methods which greatly expedite the whole Integration Testing process.

To use the framework, simply include the corresponding gem in the Gemfile, and the following lines to the end of the test_helper.rb file.

# Add more helper methods ...
require ‘capybara/rails’

class ActionDispatch::IntegrationTest
	include Capybara::DSL
end

The easy-to-use commands mentioned before are created by Capybara using a Domain Specific Language (DSL) and in order to be able to use it, every Integration written must require 'test_helper' . This is basically a mixin, so one still has the capability to access all the low-level GET/POST commands in Test-Unit.


In sum, Integration tests are vital and are carried out in the final stages of testing to ensure that the system works as a cohesive and complete unit.


Performance Tests

Conclusion