Is it possible to get the results of a test (i.e. whether all assertions have passed) in a tearDown() method? I'm running Selenium scripts, and I'd like to do some reporting from inside tearDown(), however I don't know if this is possible.
Likewise, if a tearDown() method is defined, the test runner will invoke that method after each test. For example you have a test that requires items to exist, or certain state - so you put these actions(creating object instances, initializing db, preparing rules and so on) into the setUp.
If the test fails, an exception will be raised with an explanatory message, and unittest will identify the test case as a failure. Any other exceptions will be treated as errors.
A teardown test case will execute at the end of your test run within a test folder. Teardown test cases are used to perform post test execution actions. For example, a teardown test case can be used to delete test data generated during test execution.
Internally, unittest. main() is using a few tricks to figure out the name of the module (source file) that contains the call to main() . It then imports this modules, examines it, gets a list of all classes and functions which could be tests (according the configuration) and then creates a test case for each of them.
As of March 2022 this answer is updated to support Python versions between 3.4 and 3.11 (including the newest development Python version). Classification of errors / failures is the same that is used in the output unittest
. It works without any modification of code before tearDown()
. It correctly recognizes decorators skipIf()
and expectedFailure
. It is compatible also with pytest.
Code:
import unittest class MyTest(unittest.TestCase): def tearDown(self): if hasattr(self._outcome, 'errors'): # Python 3.4 - 3.10 (These two methods have no side effects) result = self.defaultTestResult() self._feedErrorsToResult(result, self._outcome.errors) else: # Python 3.11+ result = self._outcome.result ok = all(test != self for test, text in result.errors + result.failures) # Demo output: (print short info immediately - not important) if ok: print('\nOK: %s' % (self.id(),)) for typ, errors in (('ERROR', result.errors), ('FAIL', result.failures)): for test, text in errors: if test is self: msg = [x for x in text.split('\n')[1:] if not x.startswith(' ')][0] print("\n\n%s: %s\n %s" % (typ, self.id(), msg))
If you don't need the exception info then the second half can be removed. If you want also the tracebacks then use the whole variable text
instead of msg
. It only can't recognize an unexpected success in a expectedFailure block
Example test methods:
def test_error(self): self.assertEqual(1 / 0, 1) def test_fail(self): self.assertEqual(2, 1) def test_success(self): self.assertEqual(1, 1)
Example output:
$ python3 -m unittest test ERROR: q.MyTest.test_error ZeroDivisionError: division by zero E FAIL: q.MyTest.test_fail AssertionError: 2 != 1 F OK: q.MyTest.test_success . ====================================================================== ... skipped the usual output from unittest with tracebacks ... ... Ran 3 tests in 0.001s FAILED (failures=1, errors=1)
Complete code including expectedFailure decorator example
EDIT: When I updated this solution to Python 3.11, I dropped everything related to old Python < 3.4 and also many minor notes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With