I have a discrepancy in understand of the basic unittest methods in python. Given this test file below:
import unittest, sys
class TestStringMethods(unittest.TestCase):
def setUp(self):
self.mystring = "example string"
def tearDown(self):
del self.mystring
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
with self.assertRaises(TypeError):
s.split(2)
My understanding based on what I've read ("Methods named setUp in a TestCase are run, automatically, before every test method.", http://gettingstartedwithdjango.com/en/lessons/testing-microblog/#toc1, etc) I interpret the order of events like:
1. set up self.mystring 2. run test_upper 3. tear down self.mystring 4. set up self.mystring 5. run test_isupper 6. tear down self.mystring 7. set up self.mystring 8. run test_split 9. tear down self.mystring
My co-workers interpret the docs as saying unittest works as follows:
1. set up self.mystring 2. run test_upper 3. run test_isupper 4. run test_split 5. tear down self.mystring
The setUp() and tearDown() methods allow you to define instructions that will be executed before and after each test method. They are covered in more detail in the section Organizing test code.,Such a working environment for the testing code is called a test fixture. A new TestCase instance is created as a unique test fixture used to execute each individual test method. Thus setUp(), tearDown(), and __init__() will be called once per test.,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.,When called without arguments this function removes the control-c handler if it has been installed. This function can also be used as a test decorator to temporarily remove the handler while the test is being executed:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
... -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ran 3 tests in 0.000 s OK
test_isupper(__main__.TestStringMethods)...ok test_split(__main__.TestStringMethods)...ok test_upper(__main__.TestStringMethods)...ok -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ran 3 tests in 0.001 s OK
python - m unittest test_module1 test_module2 python - m unittest test_module.TestClass python - m unittest test_module.TestClass.test_method
python - m unittest tests / test_something.py
python - m unittest - v test_module
Test Setup and Teardown within a unittest.TestCase , Test Setup and Teardown within a unittest.TestCase ,Another benefit of registering cleanups this way is that it allows the programmer to put the cleanup code next to the setup code and it protects you in the event that a subclasser forgets to call super in tearDown.,Sometimes we want to prepare a context for each test to be run under. The setUp method is run prior to each test in the class. tearDown is run at the end of every test. These methods are optional. Remember that TestCases are often used in cooperative multiple inheritance so you should be careful to always call super in these methods so that base class's setUp and tearDown methods also get called. The base implementation of TestCase provides empty setUp and tearDown methods so that they can be called without raising exceptions:
Sometimes we want to prepare a context for each test to be run under. The setUp
method is run prior to each test in the class. tearDown
is run at the end of every test. These methods are optional. Remember that TestCases are often used in cooperative multiple inheritance so you should be careful to always call super
in these methods so that base class's setUp
and tearDown
methods also get called. The base implementation of TestCase
provides empty setUp
and tearDown
methods so that they can be called without raising exceptions:
import unittest
class SomeTest(unittest.TestCase):
def setUp(self):
super(SomeTest, self).setUp()
self.mock_data = [1, 2, 3, 4, 5]
def test(self):
self.assertEqual(len(self.mock_data), 5)
def tearDown(self):
super(SomeTest, self).tearDown()
self.mock_data = []
if __name__ == '__main__':
unittest.main()
Note that in python2.7+, there is also the addCleanup
method that registers functions to be called after the test is run. In contrast to tearDown
which only gets called if setUp
succeeds, functions registered via addCleanup
will be called even in the event of an unhandled exception in setUp
. As a concrete example, this method can frequently be seen removing various mocks that were registered while the test was running:
import unittest
import some_module
class SomeOtherTest(unittest.TestCase):
def setUp(self):
super(SomeOtherTest, self).setUp()
# Replace `some_module.method`
with a `mock.Mock`
my_patch = mock.patch.object(some_module, 'method')
my_patch.start()
# When the test finishes running, put the original method back.
self.addCleanup(my_patch.stop)
The unittest module provides a rich set of tools for constructing and running tests. This section demonstrates that a small subset of the tools suffice to meet the needs of most users.,Test case instances are grouped together according to the features they test. unittest provides a mechanism for this: the test suite, represented by unittest‘s TestSuite class:,A testcase is created by subclassing unittest.TestCase. The three individual tests are defined with methods whose names start with the letters test. This naming convention informs the test runner about which methods represent tests.,Return a suite of all tests cases contained in the given module. This method searches module for classes derived from TestCase and creates an instance of the class for each test method defined for the class.
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_shuffle(self):
# make sure the shuffled sequence does not lose any elements
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, range(10))
# should raise an exception
for an immutable sequence
self.assertRaises(TypeError, random.shuffle, (1, 2, 3))
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()
... -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ran 3 tests in 0.000 s OK
suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions) unittest.TextTestRunner(verbosity = 2).run(suite)
test_choice(__main__.TestSequenceFunctions)...ok test_sample(__main__.TestSequenceFunctions)...ok test_shuffle(__main__.TestSequenceFunctions)...ok -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ran 3 tests in 0.110 s OK
python - m unittest test_module1 test_module2 python - m unittest test_module.TestClass python - m unittest test_module.TestClass.test_method
python - m unittest - v test_module
This section describes a classic and popular way how you can implement fixtures (setup and teardown test state) on a per-module/class/function basis.,If you have multiple test functions and test classes in a single module you can optionally implement the following fixture methods which will usually be called once for all the functions:,If you would rather define test functions directly at module level you can also use the following functions to implement fixtures:,teardown functions are not called if the corresponding setup function existed and failed/was skipped.
def setup_module(module): "" " setup any state specific to the execution of the given module." "" def teardown_module(module): "" " teardown any state that was previously setup with a setup_module method. "" "
@classmethod def setup_class(cls): "" " setup any state specific to the execution of the given class (which usually contains tests). "" " @classmethod def teardown_class(cls): "" " teardown any state that was previously setup with a call to setup_class. "" "
def setup_method(self, method): "" " setup any state tied to the execution of the given method in a class.setup_method is invoked for every test method of a class. "" " def teardown_method(self, method): "" " teardown any state that was previously setup with a setup_method call. "" "
def setup_function(function): "" " setup any state tied to the execution of the given function. Invoked for every test function in the module. "" " def teardown_function(function): "" " teardown any state that was previously setup with a setup_function call. "" "