I'm extending the python 2.7 unittest
framework to do some function testing. One of the things I would like to do is to stop all the tests from running inside of a test, and inside of a setUpClass()
method. Sometimes if a test fails, the program is so broken it is no longer of any use to keep testing, so I want to stop the tests from running.
I noticed that a TestResult has a shouldStop
attribute, and a stop()
method, but I'm not sure how to get access to that inside of a test.
Does anyone have any ideas? Is there a better way?
Though you won't get the usual test reports of the tests run so far, a very easy way to stop the test run from within a
TestCase
method is simply to raiseKeyboardInterrupt
inside the method.You can see how only
KeyboardInterrupt
is allowed to bubble up insideunittest
's test runner by looking at CPython's code here insidetestPartExecutor()
.Use:
In the test loop of
unittest.TestSuite
, there is abreak
condition at the start:So I am using a custom test suite like this:
with a custom test result class like this:
and my test classes are like:
Under certain conditions, I then abort the test suite; for example, the test suite starts with a login, and if that fails, I do not have to try the rest:
Then I use the test suite in the following way:
I'm not sure if there is a better way to do it, but it behaves correctly for my tests.
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:
and if you run this you get:
You can also put the
py.test.exit()
call inside a test or into a project-specific plugin.Sidenote:
py.test
natively supportspy.test --maxfail=NUM
to implement stopping after NUM failures.Sidenote2:
py.test
has only limited support for running tests in the traditionalunittest.TestCase
style.Here's another answer I came up with after a while:
First, I added a new exception:
then I added a new
assert
to my child test class:and last I overrode the
run
function to include this right below thetestMethod()
call:I like this better since any test now has the ability to stop all the tests, and there is no cpython-specific code.
I looked at the
TestCase
class and decided to subclass it. The class just overridesrun()
. I copied the method and starting at line 318 in the original class added this:It has some CPython specific code in there to tell if the test method can accept another parameter, but since I'm using CPython everywhere, this isn't an issue for me.