CSC/ECE 517 Fall 2010/ch1 1f TU

From Expertiza_Wiki
Revision as of 21:49, 5 September 2010 by Alexander (talk | contribs) (→‎Usage)
Jump to navigation Jump to search

Unit-testing frameworks for Ruby

Unit Testing

A unit is the smallest building block of a software. Such a unit can be: a class, a method, an interface etc. Unit testing is the process of validating such units of code.

Benefits

Some of the benefits are:

  • Proof of your code
  • Better design - Thinking about the tests can help us to create small design elements, thereby improving the modularity and reusability of units.
  • Safety net on bugs - Unit tests will confirm that while refactoring no additional errors were introduced.
  • Be able to detect and remove defects in a more cost effective manner compared to the other stages of testing.
  • Be able to test parts of a source code in isolation.
  • Making debugging more efficient by searching for bugs in the probable code areas.
  • Documentation - Designers can look at the unit test for a particular method and learn about its functionality.

Unit-testing frameworks

Unit Test Framework is a software tool to support writing and running unit test.

List of unit testing frameworks for Ruby

  • Test::Unit
  • RSpec
  • Shoulda
  • Cucumber

Simple Calculator Program in Ruby

This is a simple Calculator class having four methods addition,subtraction,multiplication and division.We will test each of these methods using above frameworks.

class Calculator 
 
 attr_writer :number1 
 attr_writer :number2
 
 def initialize(number1,number2)
   @number1 = number1
   @number2 = number2
 end
#-----------Addition of two numbers----------------#
 def addition
   result = @number1 + @number2
   return result
 end
#----------Subtraction of two numbers--------------#
  def subtraction
    result= @number1 - @number2
    return result
  end
#----------Multiplication of two numbers------------#
  def multiplication
    result= @number1 * @number2
    return result
  end
#-----------Division of two numbers-------------------#
 def division
   result = @number1 / @number2
   return result
 end
end

Test::Unit

Features of Test::Unit

  • It provides assertions which return pass or fail result for each unit test.
  • Each of the assertions has to be called from a context which is also called Test Method

Usage

 require "calculator"
 require "test/unit"

 class TC_Calculator < Test::Unit::TestCase
  
  
  def test_addition
    assert_equal(8,Calculator.new(3,4).addition)
   
  end
 
  def test_subtraction
   assert_same(1,Calculator.new(4,3).subtraction)
  end
 
  def test_multiplication
   assert_not_same(12,Calculator.new(3,4).multiplication)
  end
 
  def test_division
     assert_not_equal(5,Calculator.new(8,2).division)
  end
 end

If we run it as "Ruby Application " we will get the output as following

Loaded suite tc__calculator
Started
F.F.
Finished in 0.046 seconds.
 1) Failure:
  test_addition(TC_Calculator) [tc__calculator.rb:8]:
  <8> expected but was
  <7>.
 2) Failure:
  test_multiplication(TC_Calculator) [tc__calculator.rb:17]:
  <12>
  with id <25> expected to not be equal? to
  <12>
  with id <25>.
 4 tests, 4 assertions, 2 failures, 0 errors

Shoulda

Features of Shoulda

  • It allows to write code with more clarity for ruby application
  • It allows to run test with the help of Test::Unit Configurations
  • It provides context to group tests for a particular requirement

Usage

 require "rubygems"
 require "calculator"
 require "test/unit"
 require "shoulda"

 class TC_Calculator_Shoulda < Test::Unit::TestCase

  context "Calculate" do

   should "addition of two numbers " do
     assert_equal 8,Calculator.new(3,4).addition 
   end

   should "subtraction of two numbers " do
    assert_equal 1,Calculator.new(4,3).subtraction
   end

   should "multiplication of two numbers" do
    assert_equal 12,Calculator.new(3,4).multiplication
   end

   should "division of two numbers" do
    assert_equal 4,Calculator.new(12,3).division
   end

  end

 end

If we run above test as "Ruby Application" we will get the output as follows

Loaded suite tc__calculator__shoulda
Started
F...
Finished in 0.064 seconds.
 1) Failure:
    test: Calculate should addition of two numbers . (TC_Calculator_Shoulda)
    <8> expected but was
    <7>.
4 tests, 4 assertions, 1 failures, 0 errors

Cucumber

Features of Cucumber

  • Its a Behavior Driven Development(BDD) tool for Ruby.
  • It focuses on story styling plain English Text.
  • It follows GWT(Given,When,Then) pattern

Usage

Let us first create a feature file to describe about our requirements

Feature: Addition
  In order perform addition of two numbers
  As a user
  I want the sum of two numbers

  
Scenario: Add two numbers
   Given I have entered <input1>
   And   I have entered <input2>
   When  I give add
   Then  The result should be <output>

Then we will create a ruby file to give a code implementation

require 'calculator'

Before do
 @input1=3
 @input2=4
end

Given /^I have entered <input(\d+)>$/ do |arg1|
   @calc = Calculator.new(@input1,@input2)
end

When /^I give add$/ do
  @result = @calc.addition
end

Then /^The result should be <output>$/ do
 puts @result
end

Now if we run the feature file we will get the following

Feature: Addition
  In order perform addition of two numbers
  As a user
  I want the sum of two numbers

  Scenario: Add two numbers            # calculator.feature:7
    Given I have entered <input1>      # addition.rb:8
    And I have entered <input2>        # addition.rb:8
    When I give add                    # addition.rb:12
7
    Then The result should be <output> # addition.rb:16

1 scenario (1 passed)
4 steps (4 passed)
0m0.010s

RSpec

Features of RSpec
  • Use RSpec to independently specify models, views, controllers and helpers.
  • Integrated fixture loading.
  • Special generators for models and controllers that generate specs instead of tests.
  • Special RSpec matchers for even more readable specs.

Usage

Let us create our first specification file:

require "calculator"

describe "TheCalculator's", "basic calculating" do
  before(:each) do
    @cal = Calculator.new(6,2)
  end

  it "should add two numbers correctly" do
    @cal.addition.should == 8
  end

  it "should subtract two numbers correctly" do
    @cal.subtraction.should == 4
  end

  it "should multiply two numbers correctly" do
    @cal.multiplication.should == 12
  end

  it "should divide two numbers correctly" do
    @cal.division.should == 3
  end

  #...
end

This file contains nothing more than a description of an aspect of the calculator class. It contains a description of the basic calculating system. Inside the description are a set of four expectations (it "should add/subtract/multiply/divide..." and so on).

Let us associate code blocks with our expectations.

require "calculator"

 describe "TheCalculator's", "basic calculating" do
  before(:each) do
    @cal = Calculator.new(6,2)
  end

  it "should add two numbers correctly" do
    @cal.addition.should == 8
  end

  it "should subtract two numbers correctly" do
    @cal.subtraction.should == 4
  end

  it "should multiply two numbers correctly" do
    @cal.multiplication.should == 12
  end

  it "should divide two numbers correctly" do
    @cal.division.should == 3
  end

end