In this article, we’ll cover the Python unittest module and some of its common use cases.
But before that, let’s understand why we need this module in the first place.
Why should you use the unittest Module?
When you’re working with large code-bases, Application development is often categorized into two phases.
- Development Phase
- Testing Phase
Phase 1 is your development phase, where you build your core idea into a bare-bones application.
But, this is not sufficient if you actually want to use it regularly. There may have been situations that you may have missed, which can actually cause your program to work unexpectedly.
To minimize such errors, there is another phase called Testing Phase, which is aimed at testing different possible scenarios for your application, and check if it’s working correctly.
Often, if you don’t have an established framework for this phase, you may need to verify all scenarios manually, which is tedious.
To reduce the developer’s hassle, we can use the Python unittest
module and solve exactly this problem by using automated testing.
Types of testing
For an application, there are two types of tests:
- Integrated Tests
- Unit Tests
Integrated Tests are those tests that check if modules of an application work properly alongside each other.
Unit Tests are those which check small components in the application.
While we can write both Integration Tests and Unit Tests, integration tests depend hugely on your application and can combine multiple unit tests.
With all that covered, let’s now look at how we can use this module!
Python unittest Module
This module comes built-in with your Python 3+ installation, so there’s no need to install it using pip.
You can import the module by typing:
import unittest
Python unittest Methods
This module has several methods by which you can perform unittests.
The most common ones are listed in the table below.
Method | Assertion Check |
assertEqual(a,b) | a == b |
assertNotEqual(a,b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a,b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
Writing a Unit Test
We need an program to apply tests on. So let’s write one!
I will write a program that simply tries to verify the sum of elements in a list. We will write a unittest program for that.
Now, to write an individual test case, we need to inherit the unittest.TestCase
class, and then override it using some specific methods.
I will call my class MyTestClass
.
import unittest
def list_sum(my_list):
# Sums the elements of the list
return sum(my_list)
class MyTestClass(unittest.TestCase):
def test_list(self):
# Checks if the sum of the below list is as expected
my_list = [1, 2, 3, 4, 5]
self.assertEqual(list_sum(my_list), 15, "Should be 15")
def test_string(self):
# Checks if the string is 'Hello from AskPython'
my_str = 'Hi'
self.assertEqual(my_str, 'Hello from AskPython', "Should be 'Hello from AskPython'")
if __name__ == '__main__':
# Main module
unittest.main()
NOTE: To write a test method we must prefix a method name with test_
. So, any test method must be of the form test_xyz()
I’m writing a method test_list()
that checks if the sum of elements in the list equals 15, and similarly another method to check for the given string.
I’m using unittest‘s assertEqual()
method, which will run the unittest and check if this assertion holds.
Let’s now execute this file using Python.
user@AskPython $ python my_test.py
.F
======================================================================
FAIL: test_string (__main__.MyTestClass)
----------------------------------------------------------------------
Traceback (most recent call last):
File "my_test.py", line 16, in test_string
self.assertEqual(my_str, 'Hello from AskPython', "Should be 'Hello from AskPython'")
AssertionError: 'Hi' != 'Hello from AskPython'
- Hi
+ Hello from AskPython
: Should be 'Hello from AskPython'
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
As you can see, the first test passed, while the second one failed, since the strings do not match.
You’ve now written your first unittest method!
Run Unit Tests on an Application
Let’s now run unittests on another program, since you won’t be writing your entire application inside a unittest file!
Let’s write a simple application program and perform unit tests on it.
I’ll be writing a program that acts as a very simple database to store the names and marks of students.
Save the below file as test_example.py
as we’ll be referencing it in our next piece of code.
class MyClass:
# Database of {'Name': 'Marks'} dict pairs
db = dict()
num_students = 0
def add_db(self, name, marks):
self.db[name] = marks
self.num_students += 1
def rm_db(self, name):
# Removes key value pair corresponding
# to student name
if name in self.db:
del self.db[name]
else:
return f'Student with Name:{name} not in Database'
def get_marks(self, name):
if name in self.db:
return self.db[name]
else:
return f'Student with Name:{name} not in Database'
if __name__ == '__main__':
my_class = MyClass()
my_class.add_db('John', 47)
my_class.add_db('Mary', 34)
print(my_class.get_marks('John'))
The recommended method to run Unit Tests
It is a common practice to keep the testing modules separated from the core application.
So we will import the unittest
module only during the test phase.
Python allows us to do, that, by specifying the -m MODULE_NAME
option. So, our command will be:
python -m unittest -v my_test.py
We’ll use the -v
verbose option to display all helpful messages.
Now, you don’t need to write import unittest
on your application!
To run unit tests, we must write a test file for our program, similar to the one we did before. We’ll also import the MyClass
that we created earlier by referencing the file test_example.py
that we saved earlier.
import unittest
from test_example import MyClass
import random
class MyTest(unittest.TestCase):
# Init the MyClass class
my_class = MyClass()
# Database to verify test cases
database = dict()
def test_case_1(self):
print("\n\nRunning Test 1....\n\n")
name = 'John Doe'
marks = 50
self.database[name] = marks
self.my_class.add_db(name, marks)
self.assertEqual(self.database, self.my_class.db)
print(self.database)
print("\n\nFinished Test 1\n\n")
def test_case_2(self):
print("\n\nRunning Test 2....\n\n")
for i in range(5):
name = ''
for j in range(6):
name += chr(random.randint(97, 97+25))
marks = random.randint(0, 100)
self.database[name] = marks
# Insert to MyClass Database
self.my_class.add_db(name, marks)
# Now check if both databases have the same key:value pairs
self.assertEqual(self.database, self.my_class.db)
print(self.database)
print("\n\nFinished Test 2\n\n")
if __name__ == '__main__':
# Run the main unittest code
unittest.main()
Now that we’ve written the tests separately, let’s verify if it works.
python -m unittest run_tests.py

This does work, since both our tests passed!
Note that our final test database contains records from both Test1 and Test2, so it’s possible to manipulate the test mechanism based on your program!
Conclusion
Hopefully, you now understand how you can use Python’s unittest
module to perform sanity checks during the testing phase. If you have any queries, do mention them in the comment section below!
References
- JournalDev article on Python unittest Module
- RealPython article on Python unittest