Teaching Test-Driven-Development First¶
Hello world is wrong! Every textbook is doing it wrong, and here’s why:
A traditional first hello world program:
# helloworld.py
def hello_world(name):
return "Hello, {}".format(name)
if __name__ == "__main__": # w/o __name__ this'd run inadvertantly
print(hello_world("@westurner"))
And then run the program:
python ./helloworld.py
# "It should say 'Hello, @westurner!'" # (check this manually every time)
Hello world with tests (Test-Driven-Development (TDD)):
# test_helloworld.py
import unittest
class TestHelloWorld(unittest.Testcase):
def setUp(self):
# print("setUp")
self.data = {'name': 'TestName'}
def test_hello_world(self, data=None):
if data is None:
data = self.data
name = data['name']
expected_output = "Hello, {}!".format(name)
output = hello_world(name)
assert expected_output == output
self.assertEqual(ouput, expected_output)
# def tearDown(self):
# print("tearDown")
# print(json.dumps(self.data, indent=2))
And then run the automated tests:
python -m site # sys.path and $PWD (`pwd`)
python -m unittest test_helloworld # ./test_helloworld.py
python -m unittest -v test_helloworld # ./test_helloworld.py
test $? -eq 0 || echo "Tests failed! (nonzero returncode)"
Why should this first run of the tests fail?
Because we didn’t remember to import from helloworld import helloworld in test_helloworld.py.
Because, in keeping with TDD, we run the test first to make sure it actually fails without our changes.
Advantages of this Test-Driven-Development (TDD) first approach:
TDD from the start: any future breaking changes will be detected (given the completeness of the functional test specification)
This teaches Object-Orientation (OO) (Encapsulation, Separation of Concerns)
This teaches separation of data and code.
This teaches Given-When-Then.
And then what? (Teach what next?):
Testable software design patterns
Refactoring: Square, Rectangle, Triangle obj.area()
Test factories / test fixtures
Additional testing tools (beyond unittest):
pytest
Nose
WebTest, Selenium, HTML/JSON Parsing
Concepts and References: