Unit Testing with Python (Part 1) – A Simple Test

This tutorial will be the first in a small series about writing unit tests in Python, the reason it’s being split is mostly because I am learning more about it as I write! The examples below are written to Python 2.7 though I will cover 3 in the future to highlight their differences. I will also cover some of the excellent libraries available as well as their short comings.

As is the case with every language, good unit tests are an important factor when writing maintainable clean code. Python, like most languages, provides a straightforward way to achieve this. Consider the following simple functions.

def add(num1, num2):
return num1 + num2
def subtract(num1, num2):
return num1 num2
def multiply(num1, num2):
return num1 * num2

view raw


hosted with ❤ by GitHub

Nothing too unusual, just a very basic calculator that we want to write a unit test for to make sure it works as we expect. So here’s our test.

import unittest
import simple_calc as sc
class SimpleCalcTest(unittest.TestCase):
def test_add(self):
result = sc.add(1, 2)
self.assertEqual(result, 3)
def test_subtract(self):
result = sc.subtract(2, 1)
self.assertEqual(result, 1)
def test_multiply(self):
result = sc.multiply(2, 2)
self.assertEqual(result, 4)
if __name__ == '__main__':

Let’s look at the specific components;

import unittest

The unittest library, part of the standard lib, provides everything we need for our simple test.

class SimpleCalcTest(unittest.TestCase):

Subclassing TestCase means that the test runner understands what our test class is. This is because TestCase provides an interface the test runner can work with.

 def test_add(self):

The naming convention, “test_”, is important because this signifies to the test runner this is a test to be run!

 self.assertEqual(result, 3)

The whole point of our test is to guarantee the results are what we expect, in this case 1 +2 = 3, so we use an assertion. In this case assertEqual, does what we need but there’s also assertTrue, assertIn, assertIs and many alternatives, all of which provide a way to validate your results.

Here’s the output of running simple_calc_test.py:

Ran 3 tests in 0.000s


Process finished with exit code 0

Not very interesting but at least we know our functions work! Now let’s see what the result is when we make a modification to simple_calc.py so that the add function no longer behaves as expected.

 return num1 + num2 + 3

Our test expects a result of 3 but, now it’s going to get 6 back instead.

FAIL: test_add (__main__.SimpleCalcTest)
Traceback (most recent call last):
  File "simple_calc_test.py", line 9, in test_add
    self.assertEqual(result, 3)
AssertionError: 6 != 3

Ran 3 tests in 0.001s

FAILED (failures=1)

Whoops! Pretty clear that we’ve made a mistake!

This is a very simplistic example, and in reality it’s not very often you will encounter this situation. In reality your functions will call over functions to achieve their intended purpose and at that point you will need to use some kind of mocking framework, but more on that in part 2!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s