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
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import get_app, get_apps
|
||||
from django.test import _doctest as doctest
|
||||
|
@ -11,22 +14,48 @@ TEST_MODULE = 'tests'
|
|||
doctestOutputChecker = OutputChecker()
|
||||
|
||||
class DjangoTestRunner(unittest.TextTestRunner):
|
||||
|
||||
|
||||
def __init__(self, verbosity=0, failfast=False, **kwargs):
|
||||
super(DjangoTestRunner, self).__init__(verbosity=verbosity, **kwargs)
|
||||
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):
|
||||
result = super(DjangoTestRunner, self)._makeResult()
|
||||
failfast = self.failfast
|
||||
|
||||
|
||||
def stoptest_override(func):
|
||||
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()
|
||||
func(test)
|
||||
return stoptest
|
||||
|
||||
|
||||
setattr(result, 'stopTest', stoptest_override(result.stopTest))
|
||||
return result
|
||||
|
||||
|
|
|
@ -812,12 +812,10 @@ test <app or test identifier>
|
|||
Runs tests for all installed models. See :ref:`topics-testing` for more
|
||||
information.
|
||||
|
||||
--failfast
|
||||
~~~~~~~~~~
|
||||
|
||||
.. 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.
|
||||
|
||||
testserver <fixture fixture ...>
|
||||
|
|
|
@ -471,10 +471,12 @@ Models can now use a 64 bit :class:`~django.db.models.BigIntegerField` type.
|
|||
Fast Failure for Tests
|
||||
----------------------
|
||||
|
||||
The ``test`` subcommand of ``django-admin.py``, and the ``runtests.py`` 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
|
||||
encountering a failure instead of continuing with the test run.
|
||||
The :djadmin:`test` subcommand of ``django-admin.py``, and the ``runtests.py``
|
||||
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 encountering
|
||||
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
|
||||
---------------------
|
||||
|
|
|
@ -242,8 +242,8 @@ in different circumstances.
|
|||
Running tests
|
||||
=============
|
||||
|
||||
Once you've written tests, run them using your project's ``manage.py``
|
||||
utility::
|
||||
Once you've written tests, run them using the :djadmin:`test` subcommand of
|
||||
your project's ``manage.py`` utility::
|
||||
|
||||
$ ./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
|
||||
|
||||
.. 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
|
||||
-----------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue