Beginner's steps with TDD
Jason Gorman has agreed to mentor me
in the subject of TDD (Test Driven Development). I plan to document my progress
as I learn the principles behind this philosophy.

TDD can be roughly outlined as follows:
- Write a failing test for the desired functionality.
- Write the smallest amount of code that can make that test pass.
- Refactor you code, making sure your changes don’t break functionality (keep
running the tests)

As my first introduction to TDD Jason and I did some pair programming where I
implemented a simple Fibonacci function, this enabled me to see how the general
principle worked: “Test a little, program a little”, and see what sort of
obstacles I might come across, such as “What’s the next test going to be where
there is no linear progression to follow”.

I’ve given my self a quick crash course in git to document my progress, I can
commit every time I write a test or a piece of code. The history of the code
can be viewed using `gitk filename`

using a GUI or ```
git log --follow --all -p
filename
```

[1].

I don’t have the commit history for the very first Fibonacci sequence exercise
I did, however I’ve got my third attempt at it (it’s pretty similar to the
first, I’ve just been trying to internalize the concepts I’ve met so far).

```
commit 9c764e57c26e43a87954fbc9026119530c2b6ecf
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:56:42 2013 +0000
Rename testLengthOf51 -> testLengthOfFiftyOne for consistency
```diff --git a/fibonacci.py b/fibonacci.py
index b6d3197..dc28f8c 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -39,7 +39,7 @@ class TestFibonacciGenerator(unittest.TestCase):
def testLengthOfSeven(self):
self.assertRaises(ValueError, self.fibonacciGenerator, 7)
- def testLengthOf51(self):
+ def testLengthOfFiftyOne(self):
self.assertRaises(ValueError, self.fibonacciGenerator, 51)
if __name__ == '__main__':
commit b73e6566b457ae493195ab04d8baf2bf5cfaf1bf
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:56:13 2013 +0000
Code to pass testLengthOf51
diff --git a/fibonacci.py b/fibonacci.py
index d3df5a9..b6d3197 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -4,7 +4,7 @@ import unittest
class TestFibonacciGenerator(unittest.TestCase):
def fibonacciGenerator(self, length):
- if (length < 8):
+ if (length < 8 or length > 50):
raise ValueError
fibonacciSequence = [0, 1]
@@ -39,5 +39,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testLengthOfSeven(self):
self.assertRaises(ValueError, self.fibonacciGenerator, 7)
+ def testLengthOf51(self):
+ self.assertRaises(ValueError, self.fibonacciGenerator, 51)
+
if __name__ == '__main__':
unittest.main()
commit 67062b240b5d25631fd8d87fc2aeb3ae5e9b983e
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:54:41 2013 +0000
Code to pass TestLengthOfSeven
diff --git a/fibonacci.py b/fibonacci.py
index fcd695d..d3df5a9 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -4,6 +4,9 @@ import unittest
class TestFibonacciGenerator(unittest.TestCase):
def fibonacciGenerator(self, length):
+ if (length < 8):
+ raise ValueError
+
fibonacciSequence = [0, 1]
for i in range(2, length):
commit c313448c856360f009864e4c54d0fb25b47143ef
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:53:56 2013 +0000
Test for length of 7 (invalid)
diff --git a/fibonacci.py b/fibonacci.py
index 274d12b..fcd695d 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -33,5 +33,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testValidLength(self):
self.assertEquals(8, len(self.fibonacciGenerator(8)))
+ def testLengthOfSeven(self):
+ self.assertRaises(ValueError, self.fibonacciGenerator, 7)
+
if __name__ == '__main__':
unittest.main()
commit 0ad4ec5dd3a1df92fe40afb608f62ac7c8c52cda
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:50:05 2013 +0000
Changed testLength to testValidLength for clarity
diff --git a/fibonacci.py b/fibonacci.py
index 61f6f9a..274d12b 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -30,7 +30,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testSixthNumber(self):
self.assertEquals(5, self.fibonacciGenerator(8)[5])
- def testLength(self):
+ def testValidLength(self):
self.assertEquals(8, len(self.fibonacciGenerator(8)))
+
if __name__ == '__main__':
unittest.main()
commit f3c473f0fdd0d3e21f23efcf0916ea188a08f44c
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:49:13 2013 +0000
Test length of list
diff --git a/fibonacci.py b/fibonacci.py
index 783b800..61f6f9a 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -7,7 +7,7 @@ class TestFibonacciGenerator(unittest.TestCase):
fibonacciSequence = [0, 1]
for i in range(2, length):
- fibonacciSequence.append(fibonacciSequence[i-2] + fibonacciSequence[i-1])
+ fibonacciSequence.append(fibonacciSequence[i - 2] + fibonacciSequence[i - 1])
return fibonacciSequence
@@ -29,5 +29,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testSixthNumber(self):
self.assertEquals(5, self.fibonacciGenerator(8)[5])
+
+ def testLength(self):
+ self.assertEquals(8, len(self.fibonacciGenerator(8)))
if __name__ == '__main__':
unittest.main()
commit 1130cea31b30924f49fe49f3042da45a2825a460
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:47:05 2013 +0000
Test 6th number + code for that
diff --git a/fibonacci.py b/fibonacci.py
index f1b21d9..783b800 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -5,8 +5,10 @@ import unittest
class TestFibonacciGenerator(unittest.TestCase):
def fibonacciGenerator(self, length):
fibonacciSequence = [0, 1]
+
for i in range(2, length):
- fibonacciSequence.append(i - 1)
+ fibonacciSequence.append(fibonacciSequence[i-2] + fibonacciSequence[i-1])
+
return fibonacciSequence
# TESTS
@@ -24,5 +26,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testFifthNumber(self):
self.assertEquals(3, self.fibonacciGenerator(8)[4])
+
+ def testSixthNumber(self):
+ self.assertEquals(5, self.fibonacciGenerator(8)[5])
if __name__ == '__main__':
unittest.main()
commit d0256181239d47d8d975eed0bfb4277fb7a78ae2
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:40:18 2013 +0000
Test fifth number, no code needed to pass
diff --git a/fibonacci.py b/fibonacci.py
index 3400d82..f1b21d9 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -22,5 +22,7 @@ class TestFibonacciGenerator(unittest.TestCase):
def testFourthNumber(self):
self.assertEquals(2, self.fibonacciGenerator(8)[3])
+ def testFifthNumber(self):
+ self.assertEquals(3, self.fibonacciGenerator(8)[4])
if __name__ == '__main__':
unittest.main()
commit 92b636a26292f1e78078652c039347bca2027321
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:36:11 2013 +0000
Test fourth number, no code needed to pass
diff --git a/fibonacci.py b/fibonacci.py
index c43b118..3400d82 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -19,5 +19,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testThirdNumber(self):
self.assertEquals(1, self.fibonacciGenerator(8)[2])
+ def testFourthNumber(self):
+ self.assertEquals(2, self.fibonacciGenerator(8)[3])
+
if __name__ == '__main__':
unittest.main()
commit 08b1e5edc66858f2205e16f32875706e06a128e6
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 17:35:02 2013 +0000
Code for third test
diff --git a/fibonacci.py b/fibonacci.py
index 28ed083..c43b118 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -4,8 +4,12 @@ import unittest
class TestFibonacciGenerator(unittest.TestCase):
def fibonacciGenerator(self, length):
- return [0, 1]
+ fibonacciSequence = [0, 1]
+ for i in range(2, length):
+ fibonacciSequence.append(i - 1)
+ return fibonacciSequence
+ # TESTS
def testFirstNumber(self):
self.assertEquals(0, self.fibonacciGenerator(8)[0])
commit a5f3e527cdc205afeaf8df930534304a991091bd
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 14:59:51 2013 +0000
Add code for passing second test, test for third number
diff --git a/fibonacci.py b/fibonacci.py
index c9d28f3..28ed083 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -4,7 +4,7 @@ import unittest
class TestFibonacciGenerator(unittest.TestCase):
def fibonacciGenerator(self, length):
- return [0]
+ return [0, 1]
def testFirstNumber(self):
self.assertEquals(0, self.fibonacciGenerator(8)[0])
@@ -12,6 +12,8 @@ class TestFibonacciGenerator(unittest.TestCase):
def testSecondNumber(self):
self.assertEquals(1, self.fibonacciGenerator(8)[1])
+ def testThirdNumber(self):
+ self.assertEquals(1, self.fibonacciGenerator(8)[2])
if __name__ == '__main__':
unittest.main()
commit f04d7ec901640e5771a4ae816f17fbfade9ee9af
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 14:58:04 2013 +0000
Code to pass first test, test for second number
diff --git a/fibonacci.py b/fibonacci.py
index 54fe5bf..c9d28f3 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -4,11 +4,14 @@ import unittest
class TestFibonacciGenerator(unittest.TestCase):
def fibonacciGenerator(self, length):
- return [None]
+ return [0]
def testFirstNumber(self):
self.assertEquals(0, self.fibonacciGenerator(8)[0])
+ def testSecondNumber(self):
+ self.assertEquals(1, self.fibonacciGenerator(8)[1])
+
if __name__ == '__main__':
unittest.main()
commit a6a83808fb900638706ccfdbbe922b36f5e27d4d
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 14:51:39 2013 +0000
Testing first fibonacci number, implemented fibonacciGenerator function
diff --git a/fibonacci.py b/fibonacci.py
index f4dfbd8..54fe5bf 100755
--- a/fibonacci.py
+++ b/fibonacci.py
@@ -1,7 +1,14 @@
#!/usr/bin/env python2
import unittest
+
class TestFibonacciGenerator(unittest.TestCase):
+ def fibonacciGenerator(self, length):
+ return [None]
+
+ def testFirstNumber(self):
+ self.assertEquals(0, self.fibonacciGenerator(8)[0])
+
if __name__ == '__main__':
unittest.main()
commit d8bbcd07a01cc3b84a006bb8546133604bed12ba
Author: Will Price <will.price94@gmail.com>
Date: Tue Jan 29 10:16:20 2013 +0000
Skeleton
diff --git a/fibonacci.py b/fibonacci.py
new file mode 100755
index 0000000..f4dfbd8
--- /dev/null
+++ b/fibonacci.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python2
+import unittest
+
+class TestFibonacciGenerator(unittest.TestCase):
+
+if __name__ == '__main__':
+ unittest.main()

You might disagree with my steps, or marvel at my crap commit messages; I’m just
getting started with the tools and methodologies so hopefully in 6 months time
I’ll be able to look back at this and correct all my mistakes.

I’ve been using `tmux`

to organise my work, `vim`

to edit it, `git`

to save
progress and `watch`

to continually test my code (this is very handy!). I’m
reasonably pleased with this workflow, it’s both simple and flexible.
[1] - ‘–follow’ handles renames, ‘–all’ shows commits on all branches, ‘-p’
shows the changes in patch form (otherwise you just get commit messages)