The methods on your test class that inherits from unittest.TestCase() are called test cases. Test cases are what you'll write to test your code's functionality. You're using methods in a class for this because of how the unittest module is built.
As mentioned in the previous lesson, the names for the test cases should all start with test_:
def test_your_test_method_name(self):
pass
You need to name your test methods in that way because that is what informs your test runner which methods it should run. Also, remember to use verbose names for your test methods. Outside of testing, you might want to use more concise functions and method names, but test methods should be named verbosely and overly descriptive.
Build a Test Case
In this part of the lesson, you'll look at the fundamental structure of a test case. In a nutshell, you do two things:
- Call the function from the package you want to test
- Assert that its result sticks to what you expect
Assert Equal
unittest offers a whole array of assertion methods that you can use to make sure that your function returns the expected result. The Python docs have a reference as well as documentation on all of them.
A common assertion method is self.assertEqual(), which you can use to confirm whether two values are equal to each other:
def test_check_equality(self):
"""Expects the two inputs to be the same."""
self.assertEqual(your_package_name.your_function_call(argument), expected_result)
Note that the code above is not functional code but only a schema. You'd have to replace your_package_name.your_function_call(argument) with:
- The name of the package you imported
- The function you want to test
- The arguments that it receives
Also, expected_result would need to be replaced with the actual value you'd expect your function call to return if it worked correctly.
assertEqual() checks whether the first argument that you input is equal to the second argument that you input. By convention, you'll pass the function call that you want to test as the first argument and the expected result as the second argument.
Assert Raises
Another example of a unittest assertion method is self.assertRaises(), which you can use to confirm that a specific exception has been raised by your code:
def test_raises_error(self):
"""Expects the defined error to be raised - e.g., here a ValueError."""
with self.assertRaises(ValueError):
your_package_name.your_function_call(argument)
To make the code work, you'll again have to substitute the placeholders for actual values.
But enough talk about schemata and placeholder values! It's time to take your tests out of the realm of the obscure and actually implement real test cases so that you can see the unittest module in action.
An Example Test Case
To walk through an example of applying a test case in practice, you'll write a test to confirm that Python's math.floor() method works as expected:
import unittest
import math
class TestMath(unittest.TestCase):
def test_floor_rounds_down(self):
self.assertEqual(math.floor(3.4), 3)
In the first two lines of code, you import the unittest module and the module that you want to test. In this example case, that's Python's math module.
Following that, you create a new class called TestMath() that inherits from unittest.TestCase().
Inside that class, you create a method called test_floor_rounds_down() that should test whether the math.floor() method actually rounds down to the nearest integer.
To complete the test case, you write a self.assertEqual() method and pass it two arguments:
math.floor(3.4): a call to the function of themathmodule that you want to test, passing it any required input3: the expected output of the operation
As long as both expressions evaluate to the same result, self.assertEqual() will return True, and the test_floor_rounds_down() test case will successfully pass.
One Test Is Better Than No Test
The math module is much bigger than just math.floor(). As you can see, you didn't need to start out with a full test suite that covers everything in the module. You can always start by building just a single test. Like anything in programming, tests are incremental and iterative. You can keep adding tests while you keep building out your codebase.
Tasks
- Pick another function from the
mathmodule and write a test for it as another method in the sameTestMath()class.
You can keep adding tests whenever you want to make your code a little more secure and protected against unexpected effects of changes you might introduce to your codebase.
Another good moment to add a new test is when you encounter a bug that you haven't thought about before. Add a test to your test files, so that this new error will be caught in the future. Doing so assures that you won't run into the same issue again later on.
In the next lesson, you'll learn how to run your unittest test suite and interpret the results.
Additional Resources
- Python Documentation:
math— Mathematical functions - Python Documentation:
unittest— Unit testing framework
Summary: How to Plan Python Testing
Methods that inherit from unittest.TestCase()` are called test cases
- The names for the test cases should all start with
test_ assertEquals()confirms whether two values are equal to each otherassertRaises()confirms that a specific exception has been raised by your code- One test is better than no test