How to stop all tests from inside a test or setUp using unittest?
In case you are interested, here is a simple example how you could make a decision yourself about exiting a test suite cleanly with py.test:
# content of test_module.py
import pytest
counter = 0
def setup_function(func):
global counter
counter += 1
if counter >=3:
pytest.exit("decided to stop the test run")
def test_one():
pass
def test_two():
pass
def test_three():
pass
and if you run this you get:
$ pytest test_module.py
============== test session starts =================
platform linux2 -- Python 2.6.5 -- pytest-1.4.0a1
test path 1: test_module.py
test_module.py ..
!!!! Exit: decided to stop the test run !!!!!!!!!!!!
============= 2 passed in 0.08 seconds =============
You can also put the py.test.exit()
call inside a test or into a project-specific plugin.
Sidenote: py.test
natively supports py.test --maxfail=NUM
to implement stopping after NUM failures.
Sidenote2: py.test
has only limited support for running tests in the traditional unittest.TestCase
style.
Currently, you can only stop the tests at the suite level. Once you are in a TestCase
, the stop()
method for the TestResult
is not used when iterating through the tests.
Somewhat related to your question, if you are using python 2.7, you can use the -f/--failfast
flag when calling your test with python -m unittest
. This will stop the test at the first failure.
See 25.3.2.1. failfast, catch and buffer command line options
You can also consider using Nose to run your tests and use the -x, --stop
flag to stop the test early.
Here's another answer I came up with after a while:
First, I added a new exception:
class StopTests(Exception):
"""
Raise this exception in a test to stop the test run.
"""
pass
then I added a new assert
to my child test class:
def assertStopTestsIfFalse(self, statement, reason=''):
try:
assert statement
except AssertionError:
result.addFailure(self, sys.exc_info())
and last I overrode the run
function to include this right below the testMethod()
call:
except StopTests:
result.addFailure(self, sys.exc_info())
result.stop()
I like this better since any test now has the ability to stop all the tests, and there is no cpython-specific code.