Unittest is the default testing framework provided with Python. In the previous chapter, you saw how to set up unit tests using the Pytest framework. Now we’re going to see how to do the same thing using Unittest. Don’t worry, there’s very little difference.
Just as you did with Pytest, you also need to define a function containing the scenario and assertions that will enable you to validate the test. The way you organize your test files within the project remains the same. So, up to this point, there’s no change.
However, unlike Pytest, the tests must be coded in a subclass of TestCase
from the Unittest module. The scenarios are created as methods of this class.
And to execute all of the tests in the module, we need to call the main
function within the unittest
module. So, to run all the tests, we need to add a main
to the end of the file with a call to the unittest.main()
function.
if __name__ == "__main__":
unittest.main()
The TestCase
class also provides a set of methods we can use to define our assertions. Here are the most common ones:
Method | Checks that |
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(a) | bool(a) is True |
assertFalse(a) | bool(a) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(a) | a is None |
assertIsNotNone(a) | a is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsIntance(a, b) | not isinstance(a, b) |
Once you’ve finished creating your tests, you can run one of the following commands on the terminal to execute the tests. Let’s say that the test file is named filename.py
:
A test module:
python -m unittest filename
python filename.py
A specific scenario in a test module:
python -m unittest filename.<test name>
The full set of test modules within a directory:
python -m unittest discover <test directory name>/
Here’s a summary of the different steps for running a test:
Import the
unittest
module at the top of the test file.Create the test class as a subclass of
unittest.TestCase
.Build your scenario by creating a method starting with “test_.”
Add the
main
function to the end of the file.Run the relevant command for your situation on the terminal.
Now let’s write a test using the Unittest framework. In this example, we’re going to create various scenarios that will check the methods for the string
class in the test_string.py
file:
import unittest
class TestString(unittest.TestCase):
def test_should_capitalize_string(self):
string = "hello"
expected_value = "Hello"
self.assertEqual(string.capitalize(), expected_value)
def test_should_upper_string(self):
string = "hello"
expected_value = "HELLO"
self.assertEqual(string.upper(), expected_value)
def test_should_trim_string(self):
string = " hello "
expected_value = "hello"
self.assertEqual(string.strip(), expected_value)
if __name__ == "__main__":
unittest.main()
Once we’ve finished creating the tests, we can run the python -m unittest test_string
on the terminal to execute the tests and check the results.
We can see in the terminal output that three tests have been run ( Ran 3 tests in 0.000s
) and they were all successful because we see the keyword OK
.
I’m now going to introduce a deliberate error in the first test that changes the first letter to a capital letter. We’re going to give an expected result with a lowercase “h.” We’ll be able to see how this error is returned to the terminal. Here’s the result:
This screenshot contains a number of points to note. Let’s have a look at some of the important lines that will help you to debug your testing.
F..
: the first line with the letterF
indicates that the first test failed. The two dots..
indicate that the other two tests were successful.FAIL: test_should_capitalize_string
: tells us the name of the test that failed.self.assertEqual(string.capitalize(), expected_value)
: shows us the line of code that caused the test to fail.AssertionError: 'Hello' != 'hello'
: shows us the exception that was raised that caused the test to fail. In this case, an assertion failed because there is a difference between the actual test result and the expected result. The following lines give us a more detailed description of the error.FAILED (failures=1)
: the last line concludes that the module tests have failed due to one test failure.
In this screencast, we’re going to see how to set up your first tests with the Unittest framework:
Over to You!
Let’s look again at the Calculator project and the same test plan as before, so that we can add some unit tests using the Unittest test framework.
Your Mission:
Add a test package containing the test folder structure.
Create a sequence of tests for the view module using Unittest.
Create a sequence of tests for the operators module using Unittest.
You can start off by setting up the test that I’ll show you in the video below. I’m going to create a test that will check that the multiplication function behaves correctly.
Find a suggested solution on GitHub!
Let’s Recap!
Using the Unittest framework, test scenarios are created within subclasses of
TestCase
as class methods of this class.Unittest provides a set of methods that enable you to define your assertions.
You need to add the Unittest
main
function at the end of the file.Run the tests on a module using the
python -m unittest <test module name>
command. There are other commands to refine your testing.
You’ve learned a lot in this first part. Now it’s time to test your knowledge with a little quiz. Good luck!