Fixed #12364: Added graceful exit from a test run when Ctrl-C is pressed. Thanks Randy Barlow.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12034 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c35868ab9b
commit
9a55432213
|
@ -1,4 +1,7 @@
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import get_app, get_apps
|
from django.db.models import get_app, get_apps
|
||||||
from django.test import _doctest as doctest
|
from django.test import _doctest as doctest
|
||||||
|
@ -11,22 +14,48 @@ TEST_MODULE = 'tests'
|
||||||
doctestOutputChecker = OutputChecker()
|
doctestOutputChecker = OutputChecker()
|
||||||
|
|
||||||
class DjangoTestRunner(unittest.TextTestRunner):
|
class DjangoTestRunner(unittest.TextTestRunner):
|
||||||
|
|
||||||
def __init__(self, verbosity=0, failfast=False, **kwargs):
|
def __init__(self, verbosity=0, failfast=False, **kwargs):
|
||||||
super(DjangoTestRunner, self).__init__(verbosity=verbosity, **kwargs)
|
super(DjangoTestRunner, self).__init__(verbosity=verbosity, **kwargs)
|
||||||
self.failfast = failfast
|
self.failfast = failfast
|
||||||
|
self._keyboard_interrupt_intercepted = False
|
||||||
|
|
||||||
|
def run(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Runs the test suite after registering a custom signal handler
|
||||||
|
that triggers a graceful exit when Ctrl-C is pressed.
|
||||||
|
"""
|
||||||
|
self._default_keyboard_interrupt_handler = signal.signal(signal.SIGINT,
|
||||||
|
self._keyboard_interrupt_handler)
|
||||||
|
result = super(DjangoTestRunner, self).run(*args, **kwargs)
|
||||||
|
signal.signal(signal.SIGINT, self._default_keyboard_interrupt_handler)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _keyboard_interrupt_handler(self, signal_number, stack_frame):
|
||||||
|
"""
|
||||||
|
Handles Ctrl-C by setting a flag that will stop the test run when
|
||||||
|
the currently running test completes.
|
||||||
|
"""
|
||||||
|
self._keyboard_interrupt_intercepted = True
|
||||||
|
sys.stderr.write(" <Test run halted by Ctrl-C> ")
|
||||||
|
# Set the interrupt handler back to the default handler, so that
|
||||||
|
# another Ctrl-C press will trigger immediate exit.
|
||||||
|
signal.signal(signal.SIGINT, self._default_keyboard_interrupt_handler)
|
||||||
|
|
||||||
def _makeResult(self):
|
def _makeResult(self):
|
||||||
result = super(DjangoTestRunner, self)._makeResult()
|
result = super(DjangoTestRunner, self)._makeResult()
|
||||||
failfast = self.failfast
|
failfast = self.failfast
|
||||||
|
|
||||||
def stoptest_override(func):
|
def stoptest_override(func):
|
||||||
def stoptest(test):
|
def stoptest(test):
|
||||||
if failfast and not result.wasSuccessful():
|
# If we were set to failfast and the unit test failed,
|
||||||
|
# or if the user has typed Ctrl-C, report and quit
|
||||||
|
if (failfast and not result.wasSuccessful()) or \
|
||||||
|
self._keyboard_interrupt_intercepted:
|
||||||
result.stop()
|
result.stop()
|
||||||
func(test)
|
func(test)
|
||||||
return stoptest
|
return stoptest
|
||||||
|
|
||||||
setattr(result, 'stopTest', stoptest_override(result.stopTest))
|
setattr(result, 'stopTest', stoptest_override(result.stopTest))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -812,12 +812,10 @@ test <app or test identifier>
|
||||||
Runs tests for all installed models. See :ref:`topics-testing` for more
|
Runs tests for all installed models. See :ref:`topics-testing` for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
--failfast
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
|
.. django-admin-option:: --failfast
|
||||||
|
|
||||||
Use the ``--failfast`` option to stop running tests and report the failure
|
Use the :djadminopt:`--failfast` option to stop running tests and report the failure
|
||||||
immediately after a test fails.
|
immediately after a test fails.
|
||||||
|
|
||||||
testserver <fixture fixture ...>
|
testserver <fixture fixture ...>
|
||||||
|
|
|
@ -471,10 +471,12 @@ Models can now use a 64 bit :class:`~django.db.models.BigIntegerField` type.
|
||||||
Fast Failure for Tests
|
Fast Failure for Tests
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
The ``test`` subcommand of ``django-admin.py``, and the ``runtests.py`` script
|
The :djadmin:`test` subcommand of ``django-admin.py``, and the ``runtests.py``
|
||||||
used to run Django's own test suite, support a new ``--failfast`` option.
|
script used to run Django's own test suite, support a new ``--failfast`` option.
|
||||||
When specified, this option causes the test runner to exit after
|
When specified, this option causes the test runner to exit after encountering
|
||||||
encountering a failure instead of continuing with the test run.
|
a failure instead of continuing with the test run. In addition, the handling
|
||||||
|
of ``Ctrl-C`` during a test run has been improved to trigger a graceful exit
|
||||||
|
from the test run that reports details of the tests run before the interruption.
|
||||||
|
|
||||||
Improved localization
|
Improved localization
|
||||||
---------------------
|
---------------------
|
||||||
|
|
|
@ -242,8 +242,8 @@ in different circumstances.
|
||||||
Running tests
|
Running tests
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Once you've written tests, run them using your project's ``manage.py``
|
Once you've written tests, run them using the :djadmin:`test` subcommand of
|
||||||
utility::
|
your project's ``manage.py`` utility::
|
||||||
|
|
||||||
$ ./manage.py test
|
$ ./manage.py test
|
||||||
|
|
||||||
|
@ -274,6 +274,23 @@ a test case, add the name of the test method to the label::
|
||||||
|
|
||||||
$ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
|
$ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
You can now trigger a graceful exit from a test run by pressing ``Ctrl-C``.
|
||||||
|
|
||||||
|
If you press ``Ctrl-C`` while the tests are running, the test runner will
|
||||||
|
wait fur the currently running test to complete and then exit gracefully.
|
||||||
|
During a graceful exit the test runner will output details of any test
|
||||||
|
failures, report on how many tests were run and how many errors and failures
|
||||||
|
were encountered, and destroy any test databases as usual. Thus pressing
|
||||||
|
``Ctrl-C`` can be very useful if you forget to pass the :djadminopt:`--failfast`
|
||||||
|
option, notice that some tests are unexpectedly failing, and want to get details
|
||||||
|
on the failures without waiting for the full test run to complete.
|
||||||
|
|
||||||
|
If you do not want to wait for the currently running test to finish, you
|
||||||
|
can press ``Ctrl-C`` a second time and the test run will halt immediately,
|
||||||
|
but not gracefully. No details of the tests run before the interruption will
|
||||||
|
be reported, and any test databases created by the run will not be destroyed.
|
||||||
|
|
||||||
The test database
|
The test database
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue