Post

Python testing - module unittest

Without testing, how do we certain if our program works best and has no critical bugs?

Python testing - module unittest

what is unittest

Testing is an essential stage in development lifecycle. Without testing, how do we certain if our program works best and has no critical bugs?

sw dev cycle

In Python, there are several modules that we can use to test our program at ease. Now we are talking about unittest.


Start from basic

writing functions

Say we are writing an adder function like this.

And we wanna prove the function is working perfectly.

We begin with creating a new Python file as a unittest script. Say name it “test-one.py”. We will run this to test our adder function by a test case.

Do not name a file as “unittest.py” to avoid circular referencing because Python uses that name as a command.

naming a test function

Unlike operational functions, the adder for example, we should put a long clear name for test functions to tell what purpose the test function is. We are not calling them directly in the program so don’t worry to name it such a long one.

Basically we name the test function what and how it test. For example, “test_get_student_name_boy_only” to test getting student names by focusing male student only, or like above “test_adder_simple_by_both_positive” to test the function adder_simple by input 2 positive numbers.

run test

Run the test by runing the python test file.

1
python3 <unittest.py-filepath>

The result should output a dot (.) as a successful test case.

test one

add more test cases

One test case is defined by One test function. If we want more test cases, we can write as many test functions as we want.

When run it, we will see more dots means more successful test cases.

test multiple

what if test cases failed?

Let’s write a test case that expects to be failed.

You would notice at line 15 that -2 + 2 ≠ 1 for sure. When run it, it would display F means an error with a failed statement. Next is to sort out the root causes whether the test case is wrong or the program has a bug somewhere.

test multiple failed


Dealing with error handlings

When it comes with error handlings, Python uses try-except structure. We would have to design our unit testing to capture those behaviors, of course.

Let’s see how.

adder function with error handling

This example is a function that raise an error when any argument a or b is less than zero or equal.

how to test

unittest has a method to capture the error raised like below, assertRaisesRegex(). This method helps capture a certain error type with patterned message in a regular expression string.

For more info about regular expressions, please visit this article.

In case the test case wants to capture only a certain error type, we can use assertRaises().

You can follow the link below to the official document of the module unittest.


Show logs in test functions

Showing pure dots may be too plain to visualize. We can print out what and where we are testing. Try these.

simply print

Yes, we just use print() to print out any texts as we want.

The command print(self._testMethodName) means we are printing the name of the testing method. The result would be like this below.

test multiple print

logging module

We could know the module logging. This module is great to print out logs with severity levels (DEBUG, INFO, ERROR, etc.) helps us easily notice the messages and sort out to actions.

We need to import logging then setup the logger instance. After all, we can call debug() method to log the messages there in DEBUG level.

Output would be like this.

test multiple logging

I would credit this idea of logging module by this comment at Outputting data from unit test in Python.


Testing is essential.

Don’t forget to test your code before deploying on Production.

This post is licensed under CC BY 4.0 by the author.