Last time around, I finished off talking about designing tests.

How Do I Write A Test?

I’m going to be using Python throughout; this is for two reasons: I’m using Python in my day-to-day work, and it’s really nice. For people who haven’t used Python before, I don’t expect its syntax to be too big of a hurdle.

I’ve distilled my “happy path” test writing down to 5 steps:

  1. Start by making the test fail (using something like self.assert_(False)).
  2. Fill in the initialization code (either the setUp() method, or the first few lines of the test)
  3. Call the method under test
  4. Add a broken assert statement — run the test and watch it fail (for example, if you’re expecting the return value to be 1, assert that it equals 2)
  5. Fix the assert statement — run the test again and watch it pass (if it doesn’t pass, figure out why)

A common problem I encounter is figuring out what to test, but there’s a simple way to get going: start writing simple tests, and you’ll naturally start thinking of edge cases that your tests are missing.

The Anatomy of a Python Unit Test

Here’s pretty much the simplest code to set up the Python unittest framework:

import unittest 
 
class MyTest(unittest.TestCase):
  def testFoo(self):
    self.assert_(False) 
 
if __name__ == ’__main__’:
  unittest.main()

Running this code results in:

$ python basic_unittest.py
F
======================================================================
FAIL: testFoo (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "basic_unittest.py", line 5, in testFoo
    self.assert_(False)
AssertionError
 
----------------------------------------------------------------------
Ran 1 test in 0.000s
 
FAILED (failures=1)

If we were to change that, so that the assertion succeeded:

import unittest
 
class MyTest(unittest.TestCase):
  def testFoo(self):
    self.assertEquals(1, 1)
 
if __name__ == '__main__':
  unittest.main()

We get much nicer output:

$ python basic_unittest2.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
 
OK

There are two other tools that are useful, but I’ll hold off talking about them until later on: coverage.py and Pylint. I’ll cover these later on, because they’re super useful once you get a good set of tests built up.

The next entry is coming right up, later on this afternoon (hopefully). I’ll be working through a real (admittedly academic) problem, and writing unit tests as I go.

Part 3