Size: 3542
Comment:
|
Size: 4768
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
= Python UnitTest = | = Python Unittest = |
Line 11: | Line 11: |
== Test Cases == | == unittest Module == === Usage === |
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 if __name__ == '__main__': unittest.main() |
|
Line 17: | Line 42: |
Any methods with a docstring print both the method's name and the docstring. | |
Line 18: | Line 44: |
=== Setup and Teardown === | All failures or errors print tracebacks, the only difference being the label ('FAIL' or 'ERROR'). ==== Setup and Teardown ==== |
Line 34: | Line 64: |
=== Subtests === | ==== Subtests ==== |
Line 51: | Line 81: |
=== Conditional Testing === | ==== Conditional Testing ==== |
Line 67: | Line 97: |
== Test Methods == | === Test Methods === |
Line 88: | Line 118: |
||`assertRaises` || ||`with self.assertRaises(e,msg=m):` || | ||`assertRaises` || ||`with self.assertRaises(e,msg=m): ...`|| |
Line 94: | Line 124: |
== CLI Execution == | === CLI Execution === |
Line 96: | Line 126: |
Verbosity is set with `-q` and `-v` flags. | Verbosity is set with `--quiet` (`-q`) and `--verbose` (`-v`) flags. |
Line 98: | Line 128: |
The `discover` subcommand searches for files names as `test_*.py`. A search directory can be supplied additionally. | The `discover` subcommand searches for files names matching the pattern `test*.py`. A search directory can be optionally supplied using `--start-directory` (`-s`). An alternate pattern can be optionally supplied using `--pattern` (`-p`). |
Line 101: | Line 131: |
$ python -m unittest discover -s tests/ | $ python -m unittest discover -s tests/ -v |
Line 103: | Line 133: |
---- == Tests == === Bad File Inputs === To create a file with a bad encoding, try: {{{ def write_bad_file(fn): with open(fn, 'w') as f: f.write('fooß'.encode('utf-8')) f.write('barß'.encode('cp1252')) }}} |
Python Unittest
Python has a built-in test suite library. It is rudimentary, but requires no external libraries or tools.
Contents
unittest Module
Usage
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 if __name__ == '__main__': unittest.main()
Any methods with a docstring print both the method's name and the docstring.
All failures or errors print tracebacks, the only difference being the label ('FAIL' or 'ERROR').
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 --quiet (-q) and --verbose (-v) flags.
The discover subcommand searches for files names matching the pattern test*.py. A search directory can be optionally supplied using --start-directory (-s). An alternate pattern can be optionally supplied using --pattern (-p).
$ python -m unittest discover -s tests/ -v
Tests
Bad File Inputs
To create a file with a bad encoding, try:
def write_bad_file(fn): with open(fn, 'w') as f: f.write('fooß'.encode('utf-8')) f.write('barß'.encode('cp1252'))