Unit Testing
You’ll learn about the concept of unit testing in Python in this lesson.
Introduction and structure of unit testing
A unit test tests the methods in a single class. A test case tests the response of a single method to a particular set of inputs.
To do unit testing, you have to do the following:
import unittest
import fileToBeTested
orfrom fileToBeTested import *
Reminder: If you use
from file import *
you don’t have to precede every function call with the name of the file it was imported from.- Write a
class SomeName(unittest.TestCase)
. Within the class:- Define methods
setUp(self)
andtearDown(self)
, if desired. These are both optional. - Provide one or more
testSomething(self)
methods. You may include other methods, but the names of test methods must begin withtest
.
- Define methods
- At the end of the test file, put
unittest.main()
.
Role each component of unit testing play
Here’s what the unittest.main()
does. For each and every method whose name begins with test
, the unittest.main
method calls setUp()
if you have provided one. Then, it calls the test method and the tearDown()
method if you have provided one. So, every test is sandwiched between setUp
and tearDown
.
The purpose of the setUp
method is to make sure everything is in a known, pristine state before calling the test method. This way, you can make sure that the results of running one test do not affect the results of a later test.
The purpose of tearDown
is to remove artifacts (such as files) that may have been created. It is used much less frequently than setUp
.
Each test method should typically test only one function, though it may call that function many times. You can write multiple tests for the same function.
Here is a trivial example of a test method:
def test_add(self):
self.assertEqual(4, add(2, 2))
self.assertEqual(0, add(2, -2))
Assertions
If any assertion in a test method fails, the test fails and the remaining assertions in that method are not tested. Therefore, test methods should not become too long.
If the method to be tested is in a class C
and you used import C
rather than from C import *
, you need to also use the class name, for example, self.assertEqual(4, C.add(2, 2))
. The convention is to put the expected result (4) first and the function call (add
) last.
Here are the most commonly used assertion methods:
self.assertEqual(expected, actual)
self.assertAlmostEqual(expected, actual)
for floating point numbersself.assertTrue(boolean)
andassertFalse(boolean)
.
More assertion methods are given in an appendix.
The assertRaises
function
You can test whether a function raises an exception when it is supposed to, but this method has a special form. This is necessary because arguments to a function are evaluated before the function is called. For example, if you said the following:
self.assertRaises(ZeroDivisionError, 5/0)
The argument 5/0
would be evaluated and would raise the exception before assertRaises
can be called.
The solution is to pass the function name in separate from its arguments:
self.assertRaises(exception, function_name, arguments)
This allows the assertRaises
function to call the function to be tested within a try-except
block and handle it appropriately.
Common practices
When testing is not being done, a common idiom is to put a call to the main function as the last line in the code file, for example, main()
. This causes the main
method to run immediately after the file is loaded. When doing unit testing, this is undesirable. Instead, replace that line with the following:
if __name__ == '__main__':
main()
And put the following code at the end of the test file:
unittest.main()
This way, the program will be run if loaded from the program file, and the tests will be run if loaded from the test file.
Unit test example
If provided with an int
or a string
, the following section of code returns a list of digits from it:
Get hands-on with 1400+ tech skills courses.