Added TDD example using calculate_gc function.
authorJohn Blischak <jdblischak@gmail.com>
Mon, 17 Jun 2013 03:03:33 +0000 (22:03 -0500)
committerW. Trevor King <wking@tremily.us>
Fri, 1 Nov 2013 20:26:19 +0000 (13:26 -0700)
09-testing/Readme.md
09-testing/calculate_gc.py [new file with mode: 0644]
09-testing/test_calculate_gc.py [new file with mode: 0644]

index 4aa3da66866ac0b2855e5eb169a2b8fb22d5c5e7..d32a61b9d76389972ec377e59dc0edb27fe3cb67 100644 (file)
@@ -357,4 +357,79 @@ style was put forth most strongly by [Kent Beck in
 
 ## A TDD Example
 
+To illustrate TDD, let's return to the function you wrote yesterday,
+`calculate_gc`. We'll start from scratch and develop the function
+by meeting test specifications. 
+
+The beginning of the function is contained in the file `calculate_gc.py`
+in this directory. It currently takes one argument as input, but does
+nothing.
+
+```python
+def calculate_gc(x):
+    '''
+    Calculates the GC content of DNA sequence x.
+    '''
+    pass
+```
+
+The tests that we must pass are contained in the file
+`test_calculate_gc.py`. We can run the tests using nosetests.
+
+    nosetests -v test_calculate_gc.py
+
+As expected, we fail all the tests! What is the bare minimum 
+functionality we must add to pass the first test below?
+
+```python
+def test_only_G_and_C():
+    '''
+    Sequence of only G's and C's has fraction 1.0
+    '''
+    fixture = 'GGCGCCGGC'
+    result = calculate_gc(fixture)
+    assert_equal(result, 1.0)
+```
+
+And the second test?
+
+```python
+def test_half():
+    '''
+    Sequence with half G and C has fraction 0.5
+    '''
+    fixture = 'ATGC'
+    result = calculate_gc(fixture)
+    assert_equal(result, 0.5)
+```
+
+Test number three?
+
+```python
+def test_lower_case():
+    '''
+    Sequence with lower case letters
+    '''
+    fixture = 'atgc'
+    result = calculate_gc(fixture)
+    assert_equal(result, 0.5)
+```
+
+Test number four?
+
+```python
+def test_not_DNA():
+    '''
+    Raise TypeError if not DNA
+    '''
+    fixture = 'qwerty'
+    assert_raises(TypeError, calculate_gc, fixture)
+```
+
+Through this cycle of writing tests and modifying the function to pass 
+the tests, we have developed a function that behaves exactly as we 
+expect and nothing more. And the tests not only serve as documentation 
+of what the function does, but can also be easily ran again if we made 
+further modifications (regression tests). What would be the next test 
+you would write for our function?
 
diff --git a/09-testing/calculate_gc.py b/09-testing/calculate_gc.py
new file mode 100644 (file)
index 0000000..1838d4e
--- /dev/null
@@ -0,0 +1,5 @@
+def calculate_gc(x):
+    '''
+    Calculates the GC content of DNA sequence x.
+    '''
+    pass
diff --git a/09-testing/test_calculate_gc.py b/09-testing/test_calculate_gc.py
new file mode 100644 (file)
index 0000000..b270735
--- /dev/null
@@ -0,0 +1,35 @@
+from nose.tools import assert_equal, assert_almost_equal, assert_true, \
+    assert_false, assert_raises, assert_is_instance
+
+from calculate_gc import calculate_gc
+
+def test_only_G_and_C():
+    '''
+    Sequence of only G's and C's has fraction 1.0
+    '''
+    fixture = 'GGCGCCGGC'
+    result = calculate_gc(fixture)
+    assert_equal(result, 1.0)
+
+def test_half():
+    '''
+    Sequence with half G and C has fraction 0.5
+    '''
+    fixture = 'ATGC'
+    result = calculate_gc(fixture)
+    assert_equal(result, 0.5)
+
+def test_lower_case():
+    '''
+    Sequence with lower case letters
+    '''
+    fixture = 'atgc'
+    result = calculate_gc(fixture)
+    assert_equal(result, 0.5)
+
+def test_not_DNA():
+    '''
+    Raise TypeError if not DNA
+    '''
+    fixture = 'qwerty'
+    assert_raises(TypeError, calculate_gc, fixture)