Unit tests are so called because they exercise the functionality of the code by interrogating individual functions and methods. Functions and methods can often be considered the atomic units of software because they are indivisible. However, what is considered to be the smallest code unit is subjective. The body of a function can be long are short, and shorter functions are arguably more unit-like than long ones.
Thus what reasonably constitutes a code unit typically varies from project to project and language to language. A good guideline is that if the code cannot be made any simpler logically (you cannot split apart the addition operator) or practically (a function is self-contained and well defined), then it is a unit.
Unit tests are typically made of three pieces, some set-up, a number of assertions, and some tear-down. Set-up can be as simple as initializing the input values or as complex as creating and initializing concrete instances of a class. Ultimately, the test occurs when an assertion is made, comparing the observed and expected values. For example, let us test that our mean function successfully calculates the known value for a simple list.
In a notebook run the following:
from mean import *
def test_ints():
num_list = [1, 2, 3, 4, 5]
obs = mean(num_list)
exp = 3.0
assert obs == exp
The test above:
[1, 2, 3, 4, 5]
.Run the test as you would any other function:
test_ints()
What output do you expect to see?
A unit test suite is made up of many tests just like this one. A single implemented function may be tested in numerous ways.
Once again, if we want to do anything useful with our tests it makes sense to put them into a file in their own right. In a file called test_mean.py, implement the following code:
from mean import *
def test_ints():
num_list = [1, 2, 3, 4, 5]
obs = mean(num_list)
exp = 3
assert obs == exp
def test_zero():
num_list=[0,2,4,6]
obs = mean(num_list)
exp = 3
assert obs == exp
def test_double():
# This one will fail in Python 2
num_list=[1,2,3,4]
obs = mean(num_list)
exp = 2.5
assert obs == exp
def test_long():
big = 1000000
obs = mean(range(1,big))
exp = big/2.0
assert obs == exp
def test_complex():
# complex numbers are an unordered field
# however, this does NOT mean that
# the arithmetic mean of complex numbers is meaningless
num_list = [2 + 3j, 3 + 4j, -32 - 2j]
obs = mean(num_list)
exp = NotImplemented
assert obs == exp