tdd/tdd.rst
changeset 89 449760bc4089
child 109 0afd25eadf41
equal deleted inserted replaced
88:1e5c78018aa0 89:449760bc4089
       
     1 Fundamentals
       
     2 ============
       
     3 
       
     4 Test Driven Development, abbreviated as TDD is a method of software
       
     5 development which banks on the idea of writing test cases that fail for the
       
     6 code that doesn't even exist yet. The actual code is written later to pass
       
     7 the test and then refactored.
       
     8 
       
     9 Writing tests
       
    10 =============
       
    11 
       
    12 Writing a test is simple. Writing a failing test? It is much more simple.
       
    13 Let us consider a very simple program which returns the Greatest Common
       
    14 Divisor (GCD) of two numbers. Since the test cases for the code is written
       
    15 prior to the code itself, it is necessary to have a clear idea of the code
       
    16 units that our program will contain. Let us attempt to clearly define the
       
    17 code units in our case of a GCD program. Let our program contain one and
       
    18 only one function called gcd() which takes in two arguments as parameters.
       
    19 These arguments are the numbers for which GCD must be computed. The gcd()
       
    20 function returns a single value which is the GCD of the two arguments
       
    21 passed. So if we want to find out GCD of 44, 23, I will call my code unit
       
    22 as c = gcd(44, 23) where c will contain the GCD of those two numbers.
       
    23 
       
    24 Now we have defined our code units, how will we write tests? Before writing
       
    25 the test, a very fundamental question arises in our minds. How do tests
       
    26 look like? So let us answer this question first. Tests are nothing but a
       
    27 series of assertions which are either True or False depending on the
       
    28 expected behaviour of the code. We tell our tests whether our code unit
       
    29 asserts True or asserts False based on the expected behaviour of the code
       
    30 units. If we happen to run the tests now we are sure to get errors. Oh! But
       
    31 why? We don't even have the function gcd to call. The test code doesn't
       
    32 even compile! So what should we do now? So the idea is to first write the
       
    33 stubs for the code units before we start writing tests. This is necessary
       
    34 for two reasons. Firstly, by writing the stubs for the code units we will
       
    35 be able to correctly decide and fix on to the code units that we have
       
    36 planned to include in our program. We have a clear cut idea as to how our
       
    37 program is structured, how the tests must be written among other
       
    38 things. Secondly, the tests must at least compile and then fail! If the
       
    39 tests don't even compile, that doesn't mean the tests failed. It means
       
    40 it was a failure on the programmer's part. Let us define our stub::
       
    41 
       
    42   def gcd(a, b):
       
    43       pass
       
    44 
       
    45 This stub does nothing other than defining a new function called gcd which
       
    46 takes two parameters a and b for which the GCD must be calculated. The body
       
    47 of the function just contains pass which means it does nothing, i.e. empty.
       
    48 We have our stub ready. One important thing we need to keep in mind when
       
    49 we adopt TDD methodology is that we need to have a clear set of results
       
    50 defined for our code units. To put it more clearly, for every given set of
       
    51 inputs as test case we must have, before hand, the exact outputs that are
       
    52 expected for those input test cases. If we don't have that we have failed
       
    53 in the first step of the TDD methodology itself. We must never run for
       
    54 outputs for our test cases after we have the code ready or even while
       
    55 writing tests. The expected outputs/behaviour must be in our hands before
       
    56 we start writing tests. Therefore let us define our test cases and the
       
    57 expected output for those inputs. Let one of our test cases be 48 and 64
       
    58 as *a* and *b* respectively. For this test case we know that the GCD is
       
    59 16. So that is the expected output. Let our second test case be 44 and
       
    60 19 as *a* and *b* respectively. We know that their GCD is 1 by simple paper
       
    61 and pen calculation.
       
    62 
       
    63 Now we know what a test is? What are the ingredients required to write
       
    64 tests? So what else should we wait for? Let us write our first test!::
       
    65 
       
    66   tc1 = gcd(48, 64)
       
    67   if tc1 != 16:
       
    68       print "Test failed for the case a=48 and b=64. Expected 16. Obtained
       
    69           %d instead." % tc1
       
    70       exit(1)
       
    71   
       
    72   tc2 = gcd(44, 19)
       
    73   if tc2 != 1:
       
    74       print "Test failed for the case a=44 and b=19. Expected 1. Obtained
       
    75           %d instead." % tc2
       
    76       exit(1)
       
    77 
       
    78   print "All tests passed!"