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