Software Carpentry
Embedding Tests

One of the questions that frequently comes up when testing software is, "Where should I put my tests?" When writing C programs, for example, some people always put the source code in a directory called src, the libraries in another directory called lib, and the test code in a third directory called test. Others put the tests in the same directory as the source: tests for the functions in the file matrix.c go in test_matrix.c, and so forth.

Python programmers use a different convention (at least, most of them do, most of the time). Instead of separating the testing code from the code being tested, Python programmers put both in the same .py file. For example, if the file average.py contains a single function average, the tests would be included along with the function definition, like this:

def average(*values):
    if not values:
        return 0.0
    result = 0.0
    for v in values:
        result += v
    return result / len(values)

if __name__ == '__main__':
    assert average() == 0.0
    assert average(1.0) == 1.0
    assert average(1.0, 2.0) == 1.5
    assert average(1.0, 2.0, -1.0) == (2.0/3.0)

So, what are __name__ and '__main__'? The first is a variable that Python automatically creates inside each module when reading it in. If the module (i.e., the file) is being run from the command line, like this:

$ python average.py

then __name__ is assigned the string '__main__'. If the module is being imported into another program like this:

import average

then __name__ is assigned the name of the module (in this case, 'average'). To see this in action, create a Python file called t.py that contains just one line:

print "__name__ is:", __name__

Run it from the command line:

$ python t.py

It should print out:

__name__ is: __main__

Now run Python interactively, and type the import command at the prompt:

$ python
>>> import t

This time, the output is:

__name__ is: t

We can now go back and see what average.py does. The file contains:

def average(*values):
    if not values:
        return 0.0
    result = 0.0
    for v in values:
        result += v
    return result / len(values)

if __name__ == '__main__':
    assert average() == 0.0
    assert average(1.0) == 1.0
    assert average(1.0, 2.0) == 1.5
    assert average(1.0, 2.0, -1.0) == 1.0

When some other program imports this code, __name__ is set to 'average', so the tests aren't run. If someone types python average.py at the command line, on the other hand, the tests are executed, because __name__ is '__main__'.