Unittest
unittest
is a built-in testing framework for Python.
Getting Started
Create a new file in the same folder as your program called filename.test.py
. Import unittest
as well as the main program in the test file.
import unittest
import my_program
Once you have these, you can create test cases and unit tests within them. The test cases are subclasses of unittest.TestCase
, and the unit tests need to be named test_
followed by whatever naming you want to use. Any method that does not start with test_
will not be run.
setUp
and tearDown
run at the beginning and end of each unit test. setUpClass
and tearDownClass
run at the beginning and end of each test case.
class WidgetTestCase(unittest.TestCase):
def setUpClass()
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
pass
def test_default_widget_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
# You can disable tests by using this decorator
@unittest.skip("reason for skipping") # reason is not necessary
def test_widget_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
You can run your test suite by running python3 -m unittest
in the root directory of the program. This will search for files using unittest
within the current directory.
Useful Assert Types
Assertion | Description |
---|---|
assertRaises(Exception, function, *args, **kwargs) |
Assert that Exception gets raised when function is run with *args and **kwargs [6]. |
assertRegex(text, regex) |
Assert that regex pattern matches on text . |
Run Part Of Test Suite
To run only certain classes, you can pass them at the end of the python3
call:
python3 -m unittest filename.WidgetTestCase
Mocking Input
To mock a call to input
, you can utilize mock
in the unittest
library. The patch
decorator allows you to specify a default return.[4]
import unittest
from unittest.mock import patch
def answer(input=input):
ans = input('enter yes or no')
if ans == 'yes':
return 'you entered yes'
if ans == 'no':
return 'you entered no'
class Test(unittest.TestCase):
# get_input will return 'yes' during this test
@patch('builtins.input', return_value='yes')
def test_answer_yes(self, input):
self.assertEqual(answer(input=input), 'you entered yes')
@patch('builtins.input', return_value='no')
def test_answer_no(self, input):
self.assertEqual(answer(input=input), 'you entered no')
References
- https://docs.python.org/3/library/unittest.html
- https://docs.python.org/3/library/unittest.html#skipping-tests-and-expected-failures
- https://stackoverflow.com/questions/2066508/disable-individual-python-unit-tests-temporarily
- https://stackoverflow.com/questions/21046717/python-mocking-raw-input-in-unittests
- https://stackoverflow.com/questions/1068246/python-unittest-how-to-run-only-part-of-a-test-file
- https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises
Incoming Links
Last modified: 202401040446