Testing
Test Driven Development


• Implementation
• Red-Green-Refactor
• Regression Tests
Implementation


• Test what should happen
• Test what should not happen
Red-Green-Refactor
      Add a test

     Run all tests
   Write some code

  Run the tests again

    Refactor code
Regression Tests

Change environment

Change code

Is everything still working
Testing in php

$this->get("http://myserver/login.php");
$this->assertWantedPattern("Please login to continue");

$this->setField("username", "MyTestUser");
$this->setField("password", "t0ps3cr3t");
$this->clickSubmit("Login");

$this->assertWantedPattern("You are logged in");
Testing in Java

beginAt("login.jsp");
assertTextInElement("h1", "Please login to continue");

setFormElement("username", "MyTestUser");
setFormElement("password", "t0ps3cr3t");
submit();

assertTextInElement("h1", "You are logged in");
Testing in Rails

visit login_path
assert_contain "Please login to continue"

fill_in "username", :with => "MyTestUser"
fill_in "password", :with => "t0ps3cr3t"
click_button "Login"

assert_contain "You are logged in"
Test Types

• Unit
• Functional
• Integration
Unit


• Most basic level of testing
• Model tests in Rails
Unit Testing
                          class ShipTest
class Ship
                           def test_crew
 attr_accessor :captain
                             ship = Ship.new
 attr_accessor :maties
                             ship.captain = 1
                             ship.mateys = 20
 def crew
  captain + maties
                            assert_equal 21, ship.crew
 end
                           end
end
                          end
Functional


• Test lifecycle of objects
• Controller tests in Rails
Functional Testing
class ShipsController
 def enter_other_ship
  @ship = Ship.find_captain(params[:captain])
  @ship.gold += 1000
  @ship.save
  redirect_to :action => 'show_loot'
 end
end                          class ShipsControllerTest
                              def test_entering_other_ship
                               post 'enter_other_ship', :captain => "Sparrow"

                              assert_response :redirect
                              assert_equal "Black Pearl", assign(:ship).name
                              assert_equal 1000, assigns(:ship).gold
                             end
                            end
Integration

• Overall application functionalities
• Walk through a series of events
• View Tests / Stories
Integration Testing
                                    def test_attacking_other_ships
                                     Given "another ship" do |ship|
                                      @ship_to_enter = Ship.find(ship)
                                     end

                                     Given "my ship" do
Story: Attacking other ships          @my_ship = Ship.find_by_captain("Sparrow")
 As Captain Sparrow                  end
 I attack another ship
 So I can buy more rum               Given /my $number_of_mateys maties/ do |number_of_mateys|
                                      @ship_to_enter.attackers = number_of_mateys
 Scenario: Attack first ship          end
 Given another ship                  When "we attach the other ship" do
 And my ship                          @my_ship.attacks(@ship_to_enter)
 And my 20 mateys                    end
 When we attack the other ship
 Then 1 pirate dies                  Then /$pirates_lost pirate dies/ do |pirates_lost|
 And we steel 1000 pieces of gold     assert_equal @my_schip.crew - pirates_lost, @ship_to_enter.attackers
                                     end

                                     Then /we steel $pieces_of_gold pieces of gold/ do |pieces_of_gold|
                                      assert_equal pieces_of_gold, @my_ship.gold
                                     end
                                    end
Integration Testing
  Story: Attacking other ships
   As Captain Sparrow
   I attack another ship
   So I can buy more rum

   Scenario: Attack first ship
   Given another ship
   And my ship
   And my 20 mateys
   When we attack the other ship
   Then 1 pirate dies
   And we steel 1000 pieces of gold
def test_attacking_other_ships
 Given "another ship" do |ship|
  @ship_to_enter = Ship.find(ship)
 end

 Given "my ship" do
  @my_ship = Ship.find_by_captain("Sparrow")
 end

 Given /my $number_of_mateys maties/ do |number_of_mateys|
  @ship_to_enter.attackers = number_of_mateys
 end

 When "we attach the other ship" do
  @my_ship.attacks(@ship_to_enter)
 end

 Then /$pirates_lost pirate dies/ do |pirates_lost|
  assert_equal @my_schip.crew - pirates_lost, @ship_to_enter.attackers
 end

 Then /we steel $pieces_of_gold pieces of gold/ do |pieces_of_gold|
  assert_equal pieces_of_gold, @my_ship.gold
 end
end
Test Data


• Mock/stub
• Fixtures
• Factories
Mocking & Stubbing
   def test_getting_tweet_on_homepage
    response = mock
    response.stubs(:authorization).returns(true)
    response.stubs(:last_tweet).resturns("#arrrrcamp rocks")
    TwitterAPI.expects(:get_last_tweet).returns(response)

    get 'index'
    assert_equal "#arrrrcamp rocks", assigns(:tweet).body
   end



- Mocha
- Rspec
- Flex Mock
Fixtures
pirates.yml              ships.yml
 captain_jack_sparrow:   black_pearl:
  name: Jack Sparrow      name: The Black Pearl
  enemy: Royal Navy       max_crew: 85
                          captain: captain_jack_sparrow
                         interceptor:
                           name: The Interceptor
                           max_crew: 150
                           captain: captain_jack_sparrow
Factories
Factory.sequence :pirate do |n|
 "matey#{n}"
end

Factory.define :ship do |f|             should "only find big ships" do
 f.name     'Pirateship'                Factory(:ship, :max_crew => 500)
 f.max_crew 100                         Factory(:ship, :max_crew => 200)
 f.captain { Factory.next(:pirate) }
end                                     ships = Ship.big_ones
                                        assert_equal 1, ships.size
                                       end

- Factory Girl
- Machinist
- Object Daddy
- Foundry
- Fixjour
Questions

Testing

  • 1.
  • 2.
    Test Driven Development •Implementation • Red-Green-Refactor • Regression Tests
  • 3.
    Implementation • Test whatshould happen • Test what should not happen
  • 4.
    Red-Green-Refactor Add a test Run all tests Write some code Run the tests again Refactor code
  • 5.
    Regression Tests Change environment Changecode Is everything still working
  • 6.
    Testing in php $this->get("http://myserver/login.php"); $this->assertWantedPattern("Pleaselogin to continue"); $this->setField("username", "MyTestUser"); $this->setField("password", "t0ps3cr3t"); $this->clickSubmit("Login"); $this->assertWantedPattern("You are logged in");
  • 7.
    Testing in Java beginAt("login.jsp"); assertTextInElement("h1","Please login to continue"); setFormElement("username", "MyTestUser"); setFormElement("password", "t0ps3cr3t"); submit(); assertTextInElement("h1", "You are logged in");
  • 8.
    Testing in Rails visitlogin_path assert_contain "Please login to continue" fill_in "username", :with => "MyTestUser" fill_in "password", :with => "t0ps3cr3t" click_button "Login" assert_contain "You are logged in"
  • 9.
    Test Types • Unit •Functional • Integration
  • 10.
    Unit • Most basiclevel of testing • Model tests in Rails
  • 11.
    Unit Testing class ShipTest class Ship def test_crew attr_accessor :captain ship = Ship.new attr_accessor :maties ship.captain = 1 ship.mateys = 20 def crew captain + maties assert_equal 21, ship.crew end end end end
  • 12.
    Functional • Test lifecycleof objects • Controller tests in Rails
  • 13.
    Functional Testing class ShipsController def enter_other_ship @ship = Ship.find_captain(params[:captain]) @ship.gold += 1000 @ship.save redirect_to :action => 'show_loot' end end class ShipsControllerTest def test_entering_other_ship post 'enter_other_ship', :captain => "Sparrow" assert_response :redirect assert_equal "Black Pearl", assign(:ship).name assert_equal 1000, assigns(:ship).gold end end
  • 14.
    Integration • Overall applicationfunctionalities • Walk through a series of events • View Tests / Stories
  • 15.
    Integration Testing def test_attacking_other_ships Given "another ship" do |ship| @ship_to_enter = Ship.find(ship) end Given "my ship" do Story: Attacking other ships @my_ship = Ship.find_by_captain("Sparrow") As Captain Sparrow end I attack another ship So I can buy more rum Given /my $number_of_mateys maties/ do |number_of_mateys| @ship_to_enter.attackers = number_of_mateys Scenario: Attack first ship end Given another ship When "we attach the other ship" do And my ship @my_ship.attacks(@ship_to_enter) And my 20 mateys end When we attack the other ship Then 1 pirate dies Then /$pirates_lost pirate dies/ do |pirates_lost| And we steel 1000 pieces of gold assert_equal @my_schip.crew - pirates_lost, @ship_to_enter.attackers end Then /we steel $pieces_of_gold pieces of gold/ do |pieces_of_gold| assert_equal pieces_of_gold, @my_ship.gold end end
  • 16.
    Integration Testing Story: Attacking other ships As Captain Sparrow I attack another ship So I can buy more rum Scenario: Attack first ship Given another ship And my ship And my 20 mateys When we attack the other ship Then 1 pirate dies And we steel 1000 pieces of gold
  • 17.
    def test_attacking_other_ships Given"another ship" do |ship| @ship_to_enter = Ship.find(ship) end Given "my ship" do @my_ship = Ship.find_by_captain("Sparrow") end Given /my $number_of_mateys maties/ do |number_of_mateys| @ship_to_enter.attackers = number_of_mateys end When "we attach the other ship" do @my_ship.attacks(@ship_to_enter) end Then /$pirates_lost pirate dies/ do |pirates_lost| assert_equal @my_schip.crew - pirates_lost, @ship_to_enter.attackers end Then /we steel $pieces_of_gold pieces of gold/ do |pieces_of_gold| assert_equal pieces_of_gold, @my_ship.gold end end
  • 18.
    Test Data • Mock/stub •Fixtures • Factories
  • 19.
    Mocking & Stubbing def test_getting_tweet_on_homepage response = mock response.stubs(:authorization).returns(true) response.stubs(:last_tweet).resturns("#arrrrcamp rocks") TwitterAPI.expects(:get_last_tweet).returns(response) get 'index' assert_equal "#arrrrcamp rocks", assigns(:tweet).body end - Mocha - Rspec - Flex Mock
  • 20.
    Fixtures pirates.yml ships.yml captain_jack_sparrow: black_pearl: name: Jack Sparrow name: The Black Pearl enemy: Royal Navy max_crew: 85 captain: captain_jack_sparrow interceptor: name: The Interceptor max_crew: 150 captain: captain_jack_sparrow
  • 21.
    Factories Factory.sequence :pirate do|n| "matey#{n}" end Factory.define :ship do |f| should "only find big ships" do f.name 'Pirateship' Factory(:ship, :max_crew => 500) f.max_crew 100 Factory(:ship, :max_crew => 200) f.captain { Factory.next(:pirate) } end ships = Ship.big_ones assert_equal 1, ships.size end - Factory Girl - Machinist - Object Daddy - Foundry - Fixjour
  • 22.