⇤ ← Revision 1 as of 2020-05-14 18:26:27
Size: 3542
Comment:
|
Size: 4342
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 13: | Line 13: |
The basic implementation of a test case is as follows: |
|
Line 14: | Line 16: |
import unittest | |
Line 15: | Line 18: |
class Test1(unittest.TestCase): """This is a class docstring.""" def test_1(self): #This will print "test_1 (__main__.Test1) ... ok" return def test_2(self): #This will print "test_1 (__main__.Test1) ... FAIL" self.fail() def test_3(self): #This will print "test_3 (__main__.Test1) ... ERROR" raise AttributeError @u.skip('foo bar') def test_4(self): #This will print "test_3 (__main__.Test1) ... skipped 'foo bar'" return def test_5(self): """test_5""" #This will print "test_5 ... ok" (prints docstring instead of name) return if __name__ == '__main__': unittest.main() |
|
Line 16: | Line 45: |
Python UnitTest
Python has a built-in test suite library. It is rudimentary, but requires no external libraries or tools.
Contents
Test Cases
The basic implementation of a test case is as follows:
import unittest class Test1(unittest.TestCase): """This is a class docstring.""" def test_1(self): #This will print "test_1 (__main__.Test1) ... ok" return def test_2(self): #This will print "test_1 (__main__.Test1) ... FAIL" self.fail() def test_3(self): #This will print "test_3 (__main__.Test1) ... ERROR" raise AttributeError @u.skip('foo bar') def test_4(self): #This will print "test_3 (__main__.Test1) ... skipped 'foo bar'" return def test_5(self): """test_5""" #This will print "test_5 ... ok" (prints docstring instead of name) return if __name__ == '__main__': unittest.main()
Setup and Teardown
The most common reason for grouping a set of tests into a test case is shared objects. These can be generated using the TestCase.setUp() method. (A tearDown() method is also available if needed.)
class TestWidget(unittest.TestCase): def setUp(self): self.widget = Widget('The widget')\ def tearDown(self): self.widget.dispose()
Subtests
Sometimes a test needs to be run iteratively, as to test multiple possible inputs. Rather than requiring redundant coding, the subtests context will provide this functionality.
class TestEven(unittest.TestCase): def test_1(self): for i in range(0, 6): with self.subTest(i=i): self.assertEqual(i % 2, 0)
The i=i may seem redundant, but it will cause the subtest's value of i to print on execution.
Conditional Testing
Tests can be skipped conditionally. This can be used to prevent trivial test failures.
class TestVersion(unittest.TestCase): @unittest.skipIf(mylib.__version__ < (1, 3)) def test_1(self): return
Test Methods
Method |
Equivalent to... |
Usage |
assertEqual |
a == b |
self.assertEqual(a,b,msg=m) |
assertNotEqual |
a != b |
self.assertNotEqual(a,b,msg=m) |
assertGreater |
a > b |
self.assertGreater(a,b,msg=m) |
assertGreaterEqual |
a >= b |
self.assertGreaterEqual(a,b,msg=m) |
assertLesser |
a < b |
self.assertLesser(a,b,msg=m) |
assertLesserEqual |
a <= b |
self.assertLesserEqual(a,b,msg=m) |
assertTrue |
bool(a) == True |
self.assertTrue(a,msg=m) |
assertFalse |
bool(a) == False |
self.assertFalse(a,msg=m) |
assertIs |
a is b |
self.assertIs(a,b,msg=m) |
assertIsNot |
a is not |
self.assertIsNot(a,b,msg=m) |
assertIsNone |
a is None |
self.assertIsNone(a,b,msg=m) |
assertIsNotNone |
a is not None |
self.assertIsNotNone(a,b,msg=m) |
assertIn |
a in b |
self.assertIn(a,b,msg=m) |
assertNotIn |
a not in b |
self.assertNotIn(a,b,msg=m) |
assertRegex |
re.search(b,a) |
self.assertRegex(a,b) |
assertNotRegex |
not re.search(b,a) |
self.assertNotRegex(a,b) |
assertIsInstance |
isinstance(a,b) |
self.assertIsInstance(a,b,msg=m) |
assertIsNotInstance |
not isinstance(a,b) |
self.assertIsNotInstance(a,b,msg=m) |
assertRaises |
|
with self.assertRaises(e,msg=m): |
CLI Execution
Verbosity is set with -q and -v flags.
The discover subcommand searches for files names as test_*.py. A search directory can be supplied additionally.
$ python -m unittest discover -s tests/