SlideShare a Scribd company logo
Test-Driven Development



        Kerry Buckley
Clearing up some
 Misconceptions
It’s all about testing
G !
        ON
It’s all about testing
  W   R
Tests handed to coders
R !
                E
Tests handed G coders
        O N  to

  W  R
Design activity
Design is emergent
Tests drive that design
Why?
Makes you think
Focus
Documentation
Quality
…and tests
Evolution
Dirty Hacking
Automated Testing
Automated Testing
 class Adder
   def add a, b
     a + b
   end
 end

 class AdderTest < Test::Unit::TestCase
   def test_add
     adder = Adder.new
     assert_equal 4, adder.add(2, 2)
     assert_equal 2, adder.add(4, -2)
   end
 end
Are You Really Testing
     Your Code?
  class Adder
    def add a, b
      a + b
    end
  end

  class AdderTest < Test::Unit::TestCase
    def test_add
      assert_equal 4, 2 + 2
    end
  end
Test-First Development
Test-First Development
Test-First Development



 Start
Test-First Development

         Write
         tests



 Start           Failing
                  tests
Test-First Development

         Write             Write
         tests             code



 Start           Failing           Done
                  tests
Test-Driven
Development
Test-Driven
Development
Test-Driven
        Development
Clean
code
Test-Driven
        Development
Clean             Failing
code               test
Test-Driven
        Development
Clean                     Failing
code                       test




         All tests pass
Test-Driven
        Development
Clean                           Failing
code                             test



    Refactor



               All tests pass
Test-Driven
        Development
Clean                           Failing
code                             test



    Refactor



               All tests pass
Three Rules




http://tinyurl.com/threerules
Three Rules
1. Do not write any production code unless it
   is to make a failing unit test pass.




        http://tinyurl.com/threerules
Three Rules
1. Do not write any production code unless it
   is to make a failing unit test pass.
2. Do not write any more of a unit test than
   is sufficient to fail; and compilation failures
   are failures.




         http://tinyurl.com/threerules
Three Rules
1. Do not write any production code unless it
   is to make a failing unit test pass.
2. Do not write any more of a unit test than
   is sufficient to fail; and compilation failures
   are failures.
3. Do not write any more production code
   than is sufficient to pass the one failing
   unit test.
         http://tinyurl.com/threerules
State-Based
class DongleTest < Test::Unit::TestCase
  def test_wibble
    # Set up test inputs
    dongle = Dongle.new
    dongle.addString("foo")
    dongle.addRemoteResource("http://foo.com/bar")

    # Exercise functionality under test
    dongle.wibble!

    # Verify results are as expected
    assert_equal(42, dongle.answer)
  end
end
Bottom-Up
Behaviour-Driven
 Development
More Descriptive Test
       Names
class AdderTest < Test::Unit::TestCase
  def test_should_add_two_positive_numbers
    assert_equal 4, Adder.new.add(2, 2)
  end

  def test_should_add_a_positive_and_a_negative_number
    assert_equal 2, Adder.new.add(4, -2)
  end
end
RSpec

describe 'An adder' do
  it 'can add two positive numbers' do
    Adder.new.add(2, 2).should == 4
  end

  it 'can add a positive and a negative number' do
    Adder.new.add(4, -2).should == 2
  end
end
Generated
           Documentation
$ spec -f s adder_spec.rb

An adder
- can add two positive numbers
- can add a positive and a negative number

Finished in 0.005493 seconds

2 examples, 0 failures
Matchers (RSpec)

@string.should == "foo"

@array.should_not be_empty

@hash.should have_key(:foo)

@object.should be_an_instance_of String

lambda { @stack.pop }.should raise_error(StackUnderflowError)
Matchers (HamCrest)

assertThat(string, equalTo("foo"));

assertThat(array, hasItem("bar"));

assertThat(obj, instanceOf(String.class));

assertThat(number, greaterThan(42));
Outside-In
Integration Testing
Describing Features

Feature: Transferring money between two accounts

  Scenario: Simple transfer
    Given an account called 'source' containing £100
    And an account called 'destination' containing £50
    When I transfer £20 from source to destination
    Then the 'source' account should contain £80
    And the 'destination' account should contain £70
Step Implementations
Given /^an account called '(w*)' containing £(d*)$/ do |name, amount|
  @accounts ||= {}
  @accounts[name] = Account.new(amount.to_i)
end

When /^I transfer £(d*) from (w*) to (w*)$/ do |amount, from, to|
  AccountController.new.transfer @accounts[from],
                     @accounts[to],
                     amount.to_i
end

Then /^the '(w*)' account should contain £(d*)$/ do |name, amount|
  @accounts[name].balance.should == amount.to_i
end
Unit Testing
Interaction-Based
Fake Objects




© Matthew Lee High http://www.flickr.com/photos/matthigh/3045096094/
Mocks and Stubs


   Stub   Mock
Boundary Objects
Mocking Patterns
class AccountController
  def transfer from, to, amount
    from.debit amount
    to.credit amount
  end
end




class AccountController {
  public void transfer(Account from, Account  to, int amount) {
    from.debit(amount);
    to.credit(amount);
  }
}
Record → Playback →
    Run → Verify
EasyMock
public void testTransferDebitsSourceAccount() {
  AccountController controller = new AccountController();

  Account from = createMock(Account.class);
  Account to = createNiceMock(Account.class);
  from.debit(42);

  replay(from);
  replay(to);

  controller.transfer(from, to, 42);

  verify(from);
}
Expect → Run → Verify
JMock
public void testTransferDebitsSourceAccount() {
  AccountController controller = new AccountController();
  
  Account from = context.mock(Account.class);
  Account to = context.mock(Account.class);

  context.checking(new Expectations() {{
    oneOf (from).debit(42);
  }});

  controller.transfer(from, to, 42);

  context.assertIsSatisfied();
}
RSpec
describe 'Making a transfer' do
  it 'debits the source account' do
    controller = AccountController.new

    from = mock 'from'
    to = mock 'to'
    to.stub :credit
    
    from.should_receive(:debit).with 42
    
    controller.transfer from, to, 42
  end
end
Stub → Run → Verify
Mockito

public void testTransferDebitsSourceAccount() {
  AccountController controller = new AccountController();
  
  Account from = mock(Account.class);
  Account to = mock(Account.class);

  controller.transfer(from, to, 42);

  verify(from).debit(42);
}
Not-a-Mock
describe 'Making a transfer' do
  it 'debits the source account' do
    controller = AccountController.new

    from = Account.new
    to = Account.new
    
    from.stub_method :debit => nil
    to.stub_method :credit => nil
        
    controller.transfer from, to, 42
    
    from.should_have_received(:debit).with(42)
  end
end
Other Mock Features
Mix stubs and mocks
  describe 'Peter Petrelli' do
    before do
      @peter = PeterPetrelli.instance
      @claire = mock Cheerleader
      @world = mock World
      @claire.stub :save
      @world.stub :save
    end

    it 'saves the cheerleader' do
      @claire.should_receive :save
      @peter.fulfil_destiny
    end

    it 'saves the world' do
      @world.should_receive :save
      @peter.fulfil_destiny
    end
  end
Specify return values

  @object.stub(:foo).and_return 2, 4, 6

  @object.foo   #   =>   2
  @object.foo   #   =>   4
  @object.foo   #   =>   6
  @object.foo   #   =>   6
Mock or stub class
        methods

@now = Time.now
Time.stub(:now).and_return @now

@object.should_receive(:update_timestamp).with @now
Specify expected
     number of calls

@object.should_receive(:foo).once

@object.should_receive(:bar).at_least(3).times
Raise exceptions


@object.stub(:foo).and_raise RuntimeError, 'message'
Good Practices
Test Behaviour, not
 Implementation
Keep Tests Independent
One Assertion/
Expectation per Test
Stub and Mock Where
     Appropriate
If Testing is Hard, the
  Design is Probably
        Wrong
Further Reading
Introducing BDD (Dan North)
  http://dannorth.net/introducing-bdd

BDD Introduction
 http://behaviour-driven.org/Introduction

Mock Roles, Not Objects
(Freeman, Mackinnon, Pryce, Walnes)
  http://www.jmock.org/oopsla2004.pdf

BDD in Ruby (Dave Astels)
 http://blog.daveastels.com/files/BDD_Intro.pdf

More Related Content

What's hot

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
Kerry Buckley
 
Testlink_Version 0.3
Testlink_Version 0.3Testlink_Version 0.3
Testlink_Version 0.3
surbhi saxena
 

What's hot (18)

Behaviour-Driven Development
Behaviour-Driven DevelopmentBehaviour-Driven Development
Behaviour-Driven Development
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
TDD, BDD, RSpec
TDD, BDD, RSpecTDD, BDD, RSpec
TDD, BDD, RSpec
 
TDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesTDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD Techniques
 
Unit-testing and E2E testing in JS
Unit-testing and E2E testing in JSUnit-testing and E2E testing in JS
Unit-testing and E2E testing in JS
 
Software testing ... who’s responsible is it?
Software testing ... who’s responsible is it?Software testing ... who’s responsible is it?
Software testing ... who’s responsible is it?
 
Apex Testing and Best Practices
Apex Testing and Best PracticesApex Testing and Best Practices
Apex Testing and Best Practices
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for Ruby
 
Testlink_Version 0.3
Testlink_Version 0.3Testlink_Version 0.3
Testlink_Version 0.3
 
Joomla! Testing - J!DD Germany 2016
Joomla! Testing - J!DD Germany 2016Joomla! Testing - J!DD Germany 2016
Joomla! Testing - J!DD Germany 2016
 
Model-based Testing: Taking BDD/ATDD to the Next Level
Model-based Testing: Taking BDD/ATDD to the Next LevelModel-based Testing: Taking BDD/ATDD to the Next Level
Model-based Testing: Taking BDD/ATDD to the Next Level
 
Test Driven Development Introduction
Test Driven Development IntroductionTest Driven Development Introduction
Test Driven Development Introduction
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your Database
 
Writing useful automated tests for the single page applications you build
Writing useful automated tests for the single page applications you buildWriting useful automated tests for the single page applications you build
Writing useful automated tests for the single page applications you build
 
iOS Test-Driven Development
iOS Test-Driven DevelopmentiOS Test-Driven Development
iOS Test-Driven Development
 
Getting Started with Test-Driven Development at Midwest PHP 2021
Getting Started with Test-Driven Development at Midwest PHP 2021Getting Started with Test-Driven Development at Midwest PHP 2021
Getting Started with Test-Driven Development at Midwest PHP 2021
 
Software Testing
Software TestingSoftware Testing
Software Testing
 
Clean Code
Clean CodeClean Code
Clean Code
 

Similar to TDD

Bdd for-dso-1227123516572504-8
Bdd for-dso-1227123516572504-8Bdd for-dso-1227123516572504-8
Bdd for-dso-1227123516572504-8
Frédéric Delorme
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Selenium
elliando dias
 
Mercury Testdirector8.0 using Slides
Mercury Testdirector8.0 using SlidesMercury Testdirector8.0 using Slides
Mercury Testdirector8.0 using Slides
telab
 

Similar to TDD (20)

Bdd for-dso-1227123516572504-8
Bdd for-dso-1227123516572504-8Bdd for-dso-1227123516572504-8
Bdd for-dso-1227123516572504-8
 
Introduction to test_driven_development
Introduction to test_driven_developmentIntroduction to test_driven_development
Introduction to test_driven_development
 
open sta testing Certification
open sta testing Certificationopen sta testing Certification
open sta testing Certification
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Selenium
 
Testing
TestingTesting
Testing
 
The Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable DesignThe Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable Design
 
Mercury Testdirector8.0 using Slides
Mercury Testdirector8.0 using SlidesMercury Testdirector8.0 using Slides
Mercury Testdirector8.0 using Slides
 
Никита Галкин "Testing in Frontend World"
Никита Галкин "Testing in Frontend World"Никита Галкин "Testing in Frontend World"
Никита Галкин "Testing in Frontend World"
 
Tdd
TddTdd
Tdd
 
Tdd
TddTdd
Tdd
 
Developer Joy - How great teams get s%*t done
Developer Joy - How great teams get s%*t doneDeveloper Joy - How great teams get s%*t done
Developer Joy - How great teams get s%*t done
 
Test Driven
Test DrivenTest Driven
Test Driven
 
WebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
WebTest - Efficient Functional Web Testing with HtmlUnit and BeyondWebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
WebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
 
Acceptance Test Driven Development at StarWest 2014
Acceptance Test Driven Development at StarWest 2014Acceptance Test Driven Development at StarWest 2014
Acceptance Test Driven Development at StarWest 2014
 
TDD in Powershell
TDD in PowershellTDD in Powershell
TDD in Powershell
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slides
 
Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDD
 
Unit Testing - The Whys, Whens and Hows
Unit Testing - The Whys, Whens and HowsUnit Testing - The Whys, Whens and Hows
Unit Testing - The Whys, Whens and Hows
 
Behavioural Driven Development in Zf2
Behavioural Driven Development in Zf2Behavioural Driven Development in Zf2
Behavioural Driven Development in Zf2
 
Developing a Culture of Quality Code (Midwest PHP 2020)
Developing a Culture of Quality Code (Midwest PHP 2020)Developing a Culture of Quality Code (Midwest PHP 2020)
Developing a Culture of Quality Code (Midwest PHP 2020)
 

More from Kerry Buckley

What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)
Kerry Buckley
 
Background processing
Background processingBackground processing
Background processing
Kerry Buckley
 

More from Kerry Buckley (20)

Jasmine
JasmineJasmine
Jasmine
 
Testing http calls with Webmock and VCR
Testing http calls with Webmock and VCRTesting http calls with Webmock and VCR
Testing http calls with Webmock and VCR
 
BDD with cucumber
BDD with cucumberBDD with cucumber
BDD with cucumber
 
Ruby nooks & crannies
Ruby nooks & cranniesRuby nooks & crannies
Ruby nooks & crannies
 
TDD refresher
TDD refresherTDD refresher
TDD refresher
 
Javasccript MV* frameworks
Javasccript MV* frameworksJavasccript MV* frameworks
Javasccript MV* frameworks
 
7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)
 
Functional ruby
Functional rubyFunctional ruby
Functional ruby
 
Adastral Park code retreat introduction
Adastral Park code retreat introductionAdastral Park code retreat introduction
Adastral Park code retreat introduction
 
MongoMapper lightning talk
MongoMapper lightning talkMongoMapper lightning talk
MongoMapper lightning talk
 
Ruby
RubyRuby
Ruby
 
Cloud
CloudCloud
Cloud
 
The secret life of bees
The secret life of beesThe secret life of bees
The secret life of bees
 
Background processing
Background processingBackground processing
Background processing
 
Katas, Contests and Coding Dojos
Katas, Contests and Coding DojosKatas, Contests and Coding Dojos
Katas, Contests and Coding Dojos
 
Rack
RackRack
Rack
 
Doing REST Right
Doing REST RightDoing REST Right
Doing REST Right
 
Kanban and Iterationless Working
Kanban and Iterationless WorkingKanban and Iterationless Working
Kanban and Iterationless Working
 
Software Development Trends
Software Development TrendsSoftware Development Trends
Software Development Trends
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 

Recently uploaded (20)

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 

TDD

Editor's Notes

  1. Short presentation on the background and principles of TDD and BDD.
  2. Think about what the code you&amp;#x2019;re writing is supposed to do. Reduces temptation to write speculative code. Executable docs. Forces clean structure (or at least makes poor structure painful).
  3. Think about what the code you&amp;#x2019;re writing is supposed to do. Think about interfaces and responsibilities. Think about alternate paths (errors etc).
  4. Reduces temptation to write speculative code.
  5. Executable docs. (Almost) guaranteed up-to-date.
  6. Forces clean structure (or at least makes poor structure painful). Catches some regression bugs. Makes refactoring safer (meaning you&amp;#x2019;re more likely to do it).
  7. Tests help catch regression problems, enable rapid deployment and give you the confidence to refactor. But that&amp;#x2019;s just a benefit of unit testing, not TDD.
  8. Not just the evolution of the practice, but steps most people go through in their understanding of TDD.
  9. We&amp;#x2019;ve all written code this way, and probably revert to it from time to time! Manual testing (either by the developer or someone else). Works at a small scale and in the short term, but unmaintainable.
  10. Write test cases to prove that the code works. Tests provide confidence that we haven&amp;#x2019;t broken anything when making changes.
  11. Classic (but not recommended) approach is to create one test case per production class, and one test method per production method.
  12. This passes, but doesn&amp;#x2019;t actually call our method. Obviously it&amp;#x2019;s an extreme example, but it illustrates the problem of writing test cases when the code&amp;#x2019;s already there.
  13. How do we know the tests are correct? Write them first, watch them fail, then write the code and check they pass.
  14. This is an improvement, but means you have to have a fairly complete design before you start (or you are restricted to system-level integration tests, rather than unit testing each class/method.
  15. This is an improvement, but means you have to have a fairly complete design before you start (or you are restricted to system-level integration tests, rather than unit testing each class/method.
  16. This is an improvement, but means you have to have a fairly complete design before you start (or you are restricted to system-level integration tests, rather than unit testing each class/method.
  17. Subtle difference from test-first: it&amp;#x2019;s about design more than testing. Make small changes, only writing enough to pass a test. After each test, refactor code to a clean design.
  18. Cycle should repeat at least every few minutes. Sometimes several times per minute.
  19. Cycle should repeat at least every few minutes. Sometimes several times per minute.
  20. Cycle should repeat at least every few minutes. Sometimes several times per minute.
  21. Cycle should repeat at least every few minutes. Sometimes several times per minute.
  22. Cycle should repeat at least every few minutes. Sometimes several times per minute.
  23. To a large extent, BDD is &amp;#x2018;TDD done well&amp;#x2019;.
  24. We&amp;#x2019;re now specifying what the object under test should do, rather than just writing an uninformatively-named method to test it.
  25. This is RSpec, a framework specifically designed for BDD.
  26. Even if you&amp;#x2019;re only using an xUnit framework, you can extract similar information if you give your test methods descriptive names.
  27. In case the Java people were feeling left-out.
  28. Rather than guessing what low-level objects we need and building the system up from there, we start with the actual requirement at the outside of the system (user inter, and discover the need for lower-level objects as we go.
  29. Integration testing uses a state-based approach. Used for acceptance tests for new features, which then live on as regression tests.
  30. Cucumber. Now also available for Java (Cuke4Duke), but see also JBehave and EasyB.
  31. Test classes in isolation.
  32. When we ask the object to perform a specific action, it should interact in a particular way with its collaborators. But how do we make that test pass if the collaborator classes haven&amp;#x2019;t been written yet?
  33. Mocks and stubs.
  34. Stubs are used to mimic the behaviour of other parts of the system that you don&amp;#x2019;t want to use for real. Mocks are used to specify interactions. Don&amp;#x2019;t use mocks for library calls etc which you can&amp;#x2019;t control &amp;#x2013; create a thin wrapper instead, and mock calls to that (let the mocks drive the design of the wrapper API).
  35. Boundary objects can be tested using a state-based approach, as mocks are obviously not applicable here.
  36. Naive example! Also you wouldn&amp;#x2019;t really have this code when you wrote the tests/specs.
  37. Record/playback. Advantage: IDE/refactoring support. Disadvantage: doesn&amp;#x2019;t necessarily encourage writing the test first.
  38. Specify expectations in advance, then verify afterwards. Advantage: more declarative. Disadvantage: Weird syntax.
  39. Specify expectations in advance. Verified automatically.
  40. Also known as test spies.
  41. Calling methods on mocks is silent. Verify that expected methods were called afterwards.
  42. Alternative mocking framework for RSpec. Stub methods out first (on real instances), then verify that expected methods were called afterwards.
  43. Testing behaviour means calling public methods and observing what the class under test does. You should not need to use tricks to test private methods or inspect instance variables.
  44. Tests should be runnable individually and in any order. If one test depends on data set up by another, this will make it hard to maintain your test suite, and cause puzzling failures. This is what setup and teardown methods are for.
  45. If each test only asserts one aspect of behaviour, it makes it obvious what&amp;#x2019;s wrong when it fails. It also prevents the first failure from masking later assertions.
  46. Use stubs and mocks to decouple the class under test from the rest of the system. If the method under test is relying on a collaborator providing data, that can simply be stubbed &amp;#x2013;&amp;#xA0;there&amp;#x2019;s no need to assert that the query happened. Use mocks to test that the code under test is passing the right messages to its collaborators. Beware of going overboard with stubs and mocks. There&amp;#x2019;s a happy medium between not using them at all and over-using them. Don&amp;#x2019;t use stubs and mocks in integration tests (other than possibly for interaction with other systems).
  47. Listen to the tests. If they&amp;#x2019;re hard to write or brittle, it&amp;#x2019;s probably a sign that the design of the code could be improved.