SlideShare a Scribd company logo
1 of 107
Eduardo Guerra




TDD STEP
PATTERNS
Every TDD cycle is a
step in direction of
the desired
functionality.
But the path is
usually not linear...
Not at all...
There are different kinds of
steps which can be applied
in different orders...
What test should
I introduce now
   to evolve my
 functionality?
The TDD step patterns
help you to understand
the kinds of steps that
         you can make
It is important to
understant how the test
introduced will
guide the
production code
towards the desired
functionality
API
DEFINITION
How do you
test what you
can't see?
You first need to define
how the surface look like,
to verify what is inside!
You want to       ...but the test
introduce the     should verify
new elements...   functionality.
How should I
introduce a new
 programming
    element?
Create the simplest possible
    test scenario using the new
    elements and do a trivial
    implementation.

The goal of this step is to define
  the API and how the class
  clients will interact with it.
Use parameters that will
method   induce a trivial return.


         Test the expected
class    behavior when the class
         is just created.
In this test scenario,
                the return is the String
                 that is passed as the
                      argument.


@Test
public void simpleCamelCase(){
   String s = “common“;
   String r = splitCamelCase(s);
   assertEquals(s,r);
}
@Test
public void disconnected(){
   Conection c = new Connection();
   assertFalse(c.isConnected());
}


                   When a new
                  Connection is
                  created, it is
              initally disconnected.
After the test, the class and
methods are created with a
      trivial implementation.
And when I don't have
           a simple scenario?




Fake the implementation
returning a fixed value
 expected by the test.
DIFERENTIAL TEST
If you write
a new successfull test, it
does not motivate any
change on the source code.
If you add a complex test,
   you lose the quick
     feedback rithm.
How to
 increment a
functionality?
Add a test that induce a
    small increment on the
    current class functionality.


The goal of this step is to move
 forward on the TDD session,
  incrementing functionality.
FAKED
  Previous Test
 should return true




     with this new
test you will need
    to handle this
                          Next Test
                      should return false
Equivalence class partitions are
   intervals where the class
      behavior is similar.

should do X                  should
                             do Z



                       should do Y
To increment functionality,
  the test need to jump to
      another equivalence
                 partition!
@Test public void emptyStack(){
   Stack s = new Stack();
   assertTrue(s.isEmpty());
   assertEquals(0, s.size());
}

          Small increment!

@Test public void pushOneElement(){
   Stack s = new Stack();
   s.push("item");
   assertFalse(s.isEmpty());
   assertEquals(1, s.size());
}
Test the      Test with   Test with
empty class   one entry    multiple
                            entries




 0              1              *
0            1               *

Create      Introduce    Complete
class API   basic flow    behavior
A complex scenario
can be created, but
adding a single
thing in comparison
to the previous
ones.
EXCEPTIONAL LIMIT
TDD is a happy process
          when you add
          continouslly functionality



But you need to think
  about the scenarios
that your class won't
       work properly
How to define
when my class
 do not work?
Add a test that introduce an
   invalid scenario and verify if
   the class behaves accordingly.


The goal of this step is to add
on the class the capability to
handle exceptional situations.
Here my
class works!




                 Here my class
               raises an error...
Here my class
           raises an error
 According to TDD principles, that will
only be implemented if a test is created.
@Test(expected=EmptyStackException.class)
public void removeFromEmptyStack()
             throws EmptyStackException {
   Stack s = new Stack();
   s.pull();
}


                Here expected can be
              used because exception
                 can be raised in only
                             one place!
@Test
public void addOnFullStack()
              throws FullStackException {
   Stack s = new Stack(10);
   for(int i=0;i<10;i++) s.push(“item”+i);
   try{
      s.push(“overload”);
      fail();
   }catch(FullStackException e){}
}

       Here exceptions can be thrown
        before, and only the expected
               point should be verified.
EVERYTHING
WORKING
TOGETHER
On TDD, functionality
       is tested and
 introduced little by
               little.
Every test
focus on a scenario that
exercises a single
functionality.
But how they should
   work on a mixed
          scenario?
How to make sure
       that
functionalities are
working together?
Add a test scenario in which
     two or more features are
     used combined.


 The goal of this step is to verify if
the features already implemented
      are working together.
Special              Company
Account               Account
Features              Features



           Company
            Special
           Account
When you are doing
  this kind of step,
there is no problem
  to create a tests
   that are already

           green.
@Test public void coupon(){
   ShoppingCart s = new ShoppingCart();
   s.addItem(“Product“,1000);
   s.addCoupon(100,“23473495734957“);
   assertEquals(900, s.total());
}

          Different features!
@Test public void discount(){
   ShoppingCart s = new ShoppingCart();
   s.addItem(“Product“,1000);
   s.addDiscount(0.15);
   assertEquals(850, s.total());
}
@Test public void couponWithDiscount(){
   ShoppingCart s = new ShoppingCart();
   s.addItem(“Product“,1000);
   s.addCoupon(100,“23473495734957“);
   s.addDiscount(0.15);
   assertEquals(“Coupon before discount“
                765, s.total());
}
PAUSE FOR
HOUSEKEEPING
Sometimes the solution is not
 suitable for the next test.
What can I do when
the simplest solution
is not suitable for the
 next requirements?
Ignore temporarely the
     current test and refactor the
     code to a more suitable
     solution.
  The goal of this step is to work
internally on the class to provide a
    better solution for the next
           requirements.
Don't destroy everything to
 restart from the scratch...
Perform the change on
small steps and run the
  tests between them.
For some time there will be two
  solutions or data structures
     doing the same thing.
When the new solution is
ready, remove completely
the old solution.
After the refactoring,
remove the ignore from the
    test and move on!
You realise that
for the next test you
should use a three
instead of a list.
Create the new data structure


Add code to populate the tree



Add code to use data from the tree




Delete the old solution
DIVE DEEP
Sometimes you
        need to implement
              a complicated
                         logic...



If I have an auxiliary
     method or a
     helper class...
You can also feel
that this code does
not belong to the
class that you are
developing.
What can I do when I
feel that an auxiliary
 code would help on
the implementation?
Stop temporarely the current
     TDD session and dive on another
     TDD session to develop the
     auxiliary code.

 The goal of this step is to change
  the focus of the TDD session to
 allow the developer to work on a
code out of the current class scope.
Class A TDD Session    STOP
         I need a
       function that
       break strings
      that use camel
           case...
Class A TDD Session




Class B TDD Session
                         Now I can
                       explore all the
                       possibilities on
                        camel case!
I can relax and
                               continue my
                              TDD knowing
                            that camel case
                                is working

Class A TDD Session



      Class B TDD Session
When you go deep, you can
 focus on different scenarios,
 and don`t need to include all
of them on the main class test
MOCK COMPLEXITY
My class needs to
use functions from
a hardware...
My class needs to
 access a remote
         server...
What can I do when it
 is realy hard to test
 something that my
 class needs to do?
Create a test that defines a
     mock object that mimic the
     behavior responsible for the
     complicated part.

The goal is to decouple your main
 logic from the access to external
     resources, defining which
 functionalities you need from it.
Hard to test!

 Test
                           Message Server



                   The tested class

Business           needs to send a
 Class      message to a Queue.
Let's model this
              class as with
            another class that
 Test      sends the message
                   to it.
                                 Message Server




Business              Message
 Class                 Sender
Now it is easy to
           replace Message
 Test      Sender by a mock
                object!




Business
 Class            MOCK
final MessageSender mock=
         ctx.mock(MessageSender.class);
Business b = new Business(mock);

ctx.checking(new Expectations() {{
  one(mock).send(“message“);
  will(returnValue(true));
}});

boolean ret = b.businessMethod();
assertTrue(ret);


Include on the mock the
services that you need!
Can I mock the
APIs instead of
creating a new
    class?
QueueConnectionFactory f = new QueueConnectionFactory();
QueueConnection conn = f.createQueueConnection();
QueueSession session = conn.createQueueSession(false,
                               Session.AUTO_ACKNOWLEDGE);
Queue q = new Queue("world");
QueueSender sender = session.createSender(q);
TextMessage msg = session.createTextMessage();
msg.setText(parameter);
sender.send(msg);




MOCK THIS
By creating a new class you
  decouple your business class
and implement a perfect match
    of your application needs.
And how do I
 test the class
that I mocked?
The test for the class “hard
to test“ may be manual


You can incude the test of
this part on functional tests

If you decide to automate
the test, you will need to
handle this only once.
DEPENDENCE




 EXPOSURE
Using TDD we are modeling
     alone classes...
But to design a object
oriented software you need to
      define relationships and
                colaboration!
There are
                  dependencies
                 that the class
                wants to hide...

… and others
that it needs
to expose.
How can I drive my
class using tests to
 define an explicit
   dependency?
Create a test that defines a
    mock object that expects calls
    according to the dependency
    interface.

The goal is to model the contract
 between both classes, defining
 which methods are needed and
    when they will be called.
Sometimes you know by
your architecture that you
  should decouple classes.




Business             Database
 Rules                Access
Authentication       The class can
        Service
                         also be composed
                             by different
                         implementations.



  card         fingerprint
validator       validator
Scheduler                anything

  Another times, you are
  defining a hotspot and
should be prepared to deal
        with anything.
By defining the mock, you
define the API and divide
the responsibilities among
              the classes.
final Task t = ctx.mock(Task.class);
final Scheduler s = new Scheduler();

ctx.checking(new Expectations() {{
  one(t).init(s.getConfig());
  one(t).execute();
}});

s.schedule(t, 100);
Thread.sleep(110);
final Task t = ctx.mock(Task.class);
final Scheduler s = new Scheduler();

ctx.checking(new Expectations() {{
  one(t).init(s.getConfig());
  exactly(2).of(t).execute();
  will(onConsecutiveCalls(
     throwException(new RuntimeException()),
     returnValue(null));
}});

s.schedule(t, 100);
Thread.sleep(110);
BUG LOCATOR
Do you think that you
    are protected from
errors just because you
        are using TDD?
A bug can come from a
scenario that was not
      included on the
           test suite!
How should I
handle bugs when
 I'm using TDD?
Create a test that simulates the
    bug scenario and fail because
    of it. After that, fix the code to
    make the test pass.

  The goal is to locate the bug
using the tests and to make sure
 that a similar problem will not
      return in the future.
When a bug is found,
the first impulse is to
  go straight to the
code and try to fix it!
If a bug appear it is
because the tests
are not covering
that scenario.


So, the first thing that you need
  to do is to create the tests!
If you find other things wrong
     on the code, do not start
              digging deep to
                     solve all
                    of them !
KEEP
CALM
  AND


CREATE
 TESTS
Avoid the short
blanket effect!
THE STEPS
TOGETHER
to introduce a
                        programing element                                           when a bug
                                                                                      is found
                                                                      Bug
                                                 to continue        Locator
                           API                   to improve
                                                  the code
                        Definition
                                                                                          Exceptional
             to introduce                                                                    Limit
              funtionality              to introduce
                                                                   to define
                                       a programing
                                                                  exceptional
                                          element
                                                                   scenarios

    Dive               to add more                                                           Everything
    Deep               functionality
                                             Differential                                     Working
                                                                to consolidate
                                                 Test                                         Together
                                                                   features
                      if you need
                     auxiliary code
                                                               if the previous solution
                                                                     is not suitable          Pause for
                  if something is
  Mock               hard to test
                                                                                            Housekeeping
Complexity                                   to define
                                         dependences API
                                                               Dependence
                                                                Exposure

More Related Content

What's hot

Sample Chapter of Practical Unit Testing with TestNG and Mockito
Sample Chapter of Practical Unit Testing with TestNG and MockitoSample Chapter of Practical Unit Testing with TestNG and Mockito
Sample Chapter of Practical Unit Testing with TestNG and MockitoTomek Kaczanowski
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Codeslicklash
 
Easymock Tutorial
Easymock TutorialEasymock Tutorial
Easymock TutorialSbin m
 
Embrace Unit Testing
Embrace Unit TestingEmbrace Unit Testing
Embrace Unit Testingalessiopace
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And RefactoringNaresh Jain
 
Beyond Testing: Specs and Behavior Driven Development
Beyond Testing: Specs and Behavior  Driven DevelopmentBeyond Testing: Specs and Behavior  Driven Development
Beyond Testing: Specs and Behavior Driven DevelopmentRabble .
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first stepsRenato Primavera
 
Strategy and Template Pattern
Strategy and Template PatternStrategy and Template Pattern
Strategy and Template PatternJonathan Simon
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHarry Potter
 
Testdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockTestdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockschlebu
 

What's hot (20)

Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Unit Testing in Java
Unit Testing in JavaUnit Testing in Java
Unit Testing in Java
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
Sample Chapter of Practical Unit Testing with TestNG and Mockito
Sample Chapter of Practical Unit Testing with TestNG and MockitoSample Chapter of Practical Unit Testing with TestNG and Mockito
Sample Chapter of Practical Unit Testing with TestNG and Mockito
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Unit testing with java
Unit testing with javaUnit testing with java
Unit testing with java
 
JUnit Pioneer
JUnit PioneerJUnit Pioneer
JUnit Pioneer
 
Easymock Tutorial
Easymock TutorialEasymock Tutorial
Easymock Tutorial
 
Mockito
MockitoMockito
Mockito
 
Embrace Unit Testing
Embrace Unit TestingEmbrace Unit Testing
Embrace Unit Testing
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And Refactoring
 
Beyond Testing: Specs and Behavior Driven Development
Beyond Testing: Specs and Behavior  Driven DevelopmentBeyond Testing: Specs and Behavior  Driven Development
Beyond Testing: Specs and Behavior Driven Development
 
Guice
GuiceGuice
Guice
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
Creational Design Patterns
Creational Design PatternsCreational Design Patterns
Creational Design Patterns
 
Strategy and Template Pattern
Strategy and Template PatternStrategy and Template Pattern
Strategy and Template Pattern
 
1z0-808-certification-questions-sample
1z0-808-certification-questions-sample1z0-808-certification-questions-sample
1z0-808-certification-questions-sample
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Testdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockTestdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMock
 

Similar to TDD step patterns

Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It'sJim Lynch
 
Journey's diary developing a framework using tdd
Journey's diary   developing a framework using tddJourney's diary   developing a framework using tdd
Journey's diary developing a framework using tddeduardomg23
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
Data structures and algorithms lab2
Data structures and algorithms lab2Data structures and algorithms lab2
Data structures and algorithms lab2Bianca Teşilă
 
DotNet unit testing training
DotNet unit testing trainingDotNet unit testing training
DotNet unit testing trainingTom Tang
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
Java interview questions 2
Java interview questions 2Java interview questions 2
Java interview questions 2Sherihan Anver
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Iterative architecture
Iterative architectureIterative architecture
Iterative architectureJoshuaRizzo4
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Objectives Assignment 09 Applications of Stacks COS.docx
Objectives Assignment 09 Applications of Stacks COS.docxObjectives Assignment 09 Applications of Stacks COS.docx
Objectives Assignment 09 Applications of Stacks COS.docxdunhamadell
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And DrupalPeter Arato
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy CodeNaresh Jain
 
Test & behavior driven development
Test & behavior driven developmentTest & behavior driven development
Test & behavior driven developmentTristan Libersat
 

Similar to TDD step patterns (20)

Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It's
 
Journey's diary developing a framework using tdd
Journey's diary   developing a framework using tddJourney's diary   developing a framework using tdd
Journey's diary developing a framework using tdd
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Data structures and algorithms lab2
Data structures and algorithms lab2Data structures and algorithms lab2
Data structures and algorithms lab2
 
DotNet unit testing training
DotNet unit testing trainingDotNet unit testing training
DotNet unit testing training
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Java interview questions 2
Java interview questions 2Java interview questions 2
Java interview questions 2
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Iterative architecture
Iterative architectureIterative architecture
Iterative architecture
 
Refactoring Chapter11
Refactoring Chapter11Refactoring Chapter11
Refactoring Chapter11
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Test Driven
Test DrivenTest Driven
Test Driven
 
Objectives Assignment 09 Applications of Stacks COS.docx
Objectives Assignment 09 Applications of Stacks COS.docxObjectives Assignment 09 Applications of Stacks COS.docx
Objectives Assignment 09 Applications of Stacks COS.docx
 
OCP kata overview
OCP kata overviewOCP kata overview
OCP kata overview
 
Unit testing - A&BP CC
Unit testing - A&BP CCUnit testing - A&BP CC
Unit testing - A&BP CC
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And Drupal
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Solid scala
Solid scalaSolid scala
Solid scala
 
Test & behavior driven development
Test & behavior driven developmentTest & behavior driven development
Test & behavior driven development
 
JAVA LOOP.pptx
JAVA LOOP.pptxJAVA LOOP.pptx
JAVA LOOP.pptx
 

TDD step patterns

  • 2. Every TDD cycle is a step in direction of the desired functionality.
  • 3. But the path is usually not linear...
  • 5. There are different kinds of steps which can be applied in different orders...
  • 6. What test should I introduce now to evolve my functionality?
  • 7. The TDD step patterns help you to understand the kinds of steps that you can make
  • 8. It is important to understant how the test introduced will guide the production code towards the desired functionality
  • 10. How do you test what you can't see?
  • 11. You first need to define how the surface look like, to verify what is inside!
  • 12. You want to ...but the test introduce the should verify new elements... functionality.
  • 13. How should I introduce a new programming element?
  • 14. Create the simplest possible test scenario using the new elements and do a trivial implementation. The goal of this step is to define the API and how the class clients will interact with it.
  • 15. Use parameters that will method induce a trivial return. Test the expected class behavior when the class is just created.
  • 16. In this test scenario, the return is the String that is passed as the argument. @Test public void simpleCamelCase(){ String s = “common“; String r = splitCamelCase(s); assertEquals(s,r); }
  • 17. @Test public void disconnected(){ Conection c = new Connection(); assertFalse(c.isConnected()); } When a new Connection is created, it is initally disconnected.
  • 18. After the test, the class and methods are created with a trivial implementation.
  • 19. And when I don't have a simple scenario? Fake the implementation returning a fixed value expected by the test.
  • 21. If you write a new successfull test, it does not motivate any change on the source code.
  • 22. If you add a complex test, you lose the quick feedback rithm.
  • 23. How to increment a functionality?
  • 24. Add a test that induce a small increment on the current class functionality. The goal of this step is to move forward on the TDD session, incrementing functionality.
  • 25. FAKED Previous Test should return true with this new test you will need to handle this Next Test should return false
  • 26. Equivalence class partitions are intervals where the class behavior is similar. should do X should do Z should do Y
  • 27. To increment functionality, the test need to jump to another equivalence partition!
  • 28. @Test public void emptyStack(){ Stack s = new Stack(); assertTrue(s.isEmpty()); assertEquals(0, s.size()); } Small increment! @Test public void pushOneElement(){ Stack s = new Stack(); s.push("item"); assertFalse(s.isEmpty()); assertEquals(1, s.size()); }
  • 29. Test the Test with Test with empty class one entry multiple entries 0 1 *
  • 30. 0 1 * Create Introduce Complete class API basic flow behavior
  • 31. A complex scenario can be created, but adding a single thing in comparison to the previous ones.
  • 33. TDD is a happy process when you add continouslly functionality But you need to think about the scenarios that your class won't work properly
  • 34. How to define when my class do not work?
  • 35. Add a test that introduce an invalid scenario and verify if the class behaves accordingly. The goal of this step is to add on the class the capability to handle exceptional situations.
  • 36. Here my class works! Here my class raises an error...
  • 37. Here my class raises an error According to TDD principles, that will only be implemented if a test is created.
  • 38. @Test(expected=EmptyStackException.class) public void removeFromEmptyStack() throws EmptyStackException { Stack s = new Stack(); s.pull(); } Here expected can be used because exception can be raised in only one place!
  • 39. @Test public void addOnFullStack() throws FullStackException { Stack s = new Stack(10); for(int i=0;i<10;i++) s.push(“item”+i); try{ s.push(“overload”); fail(); }catch(FullStackException e){} } Here exceptions can be thrown before, and only the expected point should be verified.
  • 41. On TDD, functionality is tested and introduced little by little.
  • 42. Every test focus on a scenario that exercises a single functionality.
  • 43. But how they should work on a mixed scenario?
  • 44. How to make sure that functionalities are working together?
  • 45. Add a test scenario in which two or more features are used combined. The goal of this step is to verify if the features already implemented are working together.
  • 46. Special Company Account Account Features Features Company Special Account
  • 47. When you are doing this kind of step, there is no problem to create a tests that are already green.
  • 48. @Test public void coupon(){ ShoppingCart s = new ShoppingCart(); s.addItem(“Product“,1000); s.addCoupon(100,“23473495734957“); assertEquals(900, s.total()); } Different features! @Test public void discount(){ ShoppingCart s = new ShoppingCart(); s.addItem(“Product“,1000); s.addDiscount(0.15); assertEquals(850, s.total()); }
  • 49. @Test public void couponWithDiscount(){ ShoppingCart s = new ShoppingCart(); s.addItem(“Product“,1000); s.addCoupon(100,“23473495734957“); s.addDiscount(0.15); assertEquals(“Coupon before discount“ 765, s.total()); }
  • 51. Sometimes the solution is not suitable for the next test.
  • 52. What can I do when the simplest solution is not suitable for the next requirements?
  • 53. Ignore temporarely the current test and refactor the code to a more suitable solution. The goal of this step is to work internally on the class to provide a better solution for the next requirements.
  • 54. Don't destroy everything to restart from the scratch...
  • 55. Perform the change on small steps and run the tests between them.
  • 56. For some time there will be two solutions or data structures doing the same thing.
  • 57. When the new solution is ready, remove completely the old solution.
  • 58. After the refactoring, remove the ignore from the test and move on!
  • 59. You realise that for the next test you should use a three instead of a list.
  • 60. Create the new data structure Add code to populate the tree Add code to use data from the tree Delete the old solution
  • 62. Sometimes you need to implement a complicated logic... If I have an auxiliary method or a helper class...
  • 63. You can also feel that this code does not belong to the class that you are developing.
  • 64. What can I do when I feel that an auxiliary code would help on the implementation?
  • 65. Stop temporarely the current TDD session and dive on another TDD session to develop the auxiliary code. The goal of this step is to change the focus of the TDD session to allow the developer to work on a code out of the current class scope.
  • 66. Class A TDD Session STOP I need a function that break strings that use camel case...
  • 67. Class A TDD Session Class B TDD Session Now I can explore all the possibilities on camel case!
  • 68. I can relax and continue my TDD knowing that camel case is working Class A TDD Session Class B TDD Session
  • 69. When you go deep, you can focus on different scenarios, and don`t need to include all of them on the main class test
  • 71. My class needs to use functions from a hardware...
  • 72. My class needs to access a remote server...
  • 73. What can I do when it is realy hard to test something that my class needs to do?
  • 74. Create a test that defines a mock object that mimic the behavior responsible for the complicated part. The goal is to decouple your main logic from the access to external resources, defining which functionalities you need from it.
  • 75. Hard to test! Test Message Server The tested class Business needs to send a Class message to a Queue.
  • 76. Let's model this class as with another class that Test sends the message to it. Message Server Business Message Class Sender
  • 77. Now it is easy to replace Message Test Sender by a mock object! Business Class MOCK
  • 78. final MessageSender mock= ctx.mock(MessageSender.class); Business b = new Business(mock); ctx.checking(new Expectations() {{ one(mock).send(“message“); will(returnValue(true)); }}); boolean ret = b.businessMethod(); assertTrue(ret); Include on the mock the services that you need!
  • 79. Can I mock the APIs instead of creating a new class?
  • 80. QueueConnectionFactory f = new QueueConnectionFactory(); QueueConnection conn = f.createQueueConnection(); QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); Queue q = new Queue("world"); QueueSender sender = session.createSender(q); TextMessage msg = session.createTextMessage(); msg.setText(parameter); sender.send(msg); MOCK THIS
  • 81. By creating a new class you decouple your business class and implement a perfect match of your application needs.
  • 82. And how do I test the class that I mocked?
  • 83. The test for the class “hard to test“ may be manual You can incude the test of this part on functional tests If you decide to automate the test, you will need to handle this only once.
  • 85. Using TDD we are modeling alone classes...
  • 86. But to design a object oriented software you need to define relationships and colaboration!
  • 87. There are dependencies that the class wants to hide... … and others that it needs to expose.
  • 88. How can I drive my class using tests to define an explicit dependency?
  • 89. Create a test that defines a mock object that expects calls according to the dependency interface. The goal is to model the contract between both classes, defining which methods are needed and when they will be called.
  • 90. Sometimes you know by your architecture that you should decouple classes. Business Database Rules Access
  • 91. Authentication The class can Service also be composed by different implementations. card fingerprint validator validator
  • 92. Scheduler anything Another times, you are defining a hotspot and should be prepared to deal with anything.
  • 93. By defining the mock, you define the API and divide the responsibilities among the classes.
  • 94. final Task t = ctx.mock(Task.class); final Scheduler s = new Scheduler(); ctx.checking(new Expectations() {{ one(t).init(s.getConfig()); one(t).execute(); }}); s.schedule(t, 100); Thread.sleep(110);
  • 95. final Task t = ctx.mock(Task.class); final Scheduler s = new Scheduler(); ctx.checking(new Expectations() {{ one(t).init(s.getConfig()); exactly(2).of(t).execute(); will(onConsecutiveCalls( throwException(new RuntimeException()), returnValue(null)); }}); s.schedule(t, 100); Thread.sleep(110);
  • 97. Do you think that you are protected from errors just because you are using TDD?
  • 98. A bug can come from a scenario that was not included on the test suite!
  • 99. How should I handle bugs when I'm using TDD?
  • 100. Create a test that simulates the bug scenario and fail because of it. After that, fix the code to make the test pass. The goal is to locate the bug using the tests and to make sure that a similar problem will not return in the future.
  • 101. When a bug is found, the first impulse is to go straight to the code and try to fix it!
  • 102. If a bug appear it is because the tests are not covering that scenario. So, the first thing that you need to do is to create the tests!
  • 103. If you find other things wrong on the code, do not start digging deep to solve all of them !
  • 107. to introduce a programing element when a bug is found Bug to continue Locator API to improve the code Definition Exceptional to introduce Limit funtionality to introduce to define a programing exceptional element scenarios Dive to add more Everything Deep functionality Differential Working to consolidate Test Together features if you need auxiliary code if the previous solution is not suitable Pause for if something is Mock hard to test Housekeeping Complexity to define dependences API Dependence Exposure