Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #12364: Added graceful exit from a test run when Ctrl-C is pres…

…sed. Thanks Randy Barlow.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12034 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 9a554322139e5c65b4b40bc538ca263a922c824f 1 parent c35868a
@kmtracey kmtracey authored
View
39 django/test/simple.py
@@ -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 @@
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
View
6 docs/ref/django-admin.txt
@@ -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 ...>
View
10 docs/releases/1.2.txt
@@ -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
---------------------
View
21 docs/topics/testing.txt
@@ -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
-----------------
Please sign in to comment.
Something went wrong with that request. Please try again.