Testing in programming is a best practice that all developers should undertand and utilize. A testing unit should focus on one tiny bit of functionality and prove it correct. Each test unit must be fully independent. Each test must be able to run alone, and also within the test suite, regardless of the order that they are called. The implication of this rule is that each test must be loaded with a fresh dataset and may have to do some cleanup afterwards. This is usually handled by setUp()
and tearDown()
methods.
Example
Here is tests.py
import unittest import functions class TestClass(unittest.TestCase): def test_multiplication(self): self.assertEqual(functions.multiply(3,3), 9, "should be 9") if __name__ == '__main__': unittest.main()
Here is functions.py
def add(num1, num2): return num1 + num2; def multiply(num1, num2): return num1 * num2;
setUp and testDown functions
Tests can be numerous, and their set-up can be repetitive. Luckily, we can factor out set-up code by implementing a method called setUp()
, which the testing framework will automatically call for every single test we run. Note that the order in which the various tests will be run is determined by sorting the test method names with respect to the built-in ordering for strings. If the setUp()
method raises an exception while the test is running, the framework will consider the test to have suffered an error, and the test method will not be executed. We can provide a tearDown()
method that tidies up after the test method has been run. If setUp()
succeeded, tearDown()
will be run whether the test method succeeded or not.
class TestClass(unittest.TestCase): def setUp(self): print("set up") def test_multiplication(self): self.assertEqual(functions.multiply(3,3), 9, "should be 9") def tearDown(self): print("tear down") if __name__ == '__main__': unittest.main()
Test Suite
It is recommended that we use TestCase implementations to group tests together according to the features we test.
import unittest import functions from tests import TestClass def suite(): suite = unittest.TestSuite() suite.addTest(TestClass('test_multiplication')) return suite if __name__ == '__main__': runner = unittest.TextTestRunner() runner.run(suite())
class TestClass(unittest.TestCase): def setUp(self): print("set up") def test_multiplication(self): self.assertEqual(functions.multiply(3,3), 9, "should be 9") def tearDown(self): print("tear down")
How to skip tests
Skipping a test is simply a matter of using the skip()
decorator or one of its conditional variants, calling TestCase.skipTest()
within a setUp()
or test method, or raising SkipTest
directly.
class TestClass(unittest.TestCase): def setUp(self): print("set up") @unittest.skip("demonstrating skipping") def test_multiplication(self): self.assertEqual(functions.multiply(3,3), 9, "should be 9") def tearDown(self): print("tear down") if __name__ == '__main__': unittest.main()
Testing with Pytest