Ticket #11613: ticket_11613.patch

File ticket_11613.patch, 7.5 KB (added by Randy Barlow, 9 years ago)

Alrighty, this patch will do the trick!

  • django/test/simple.py

     
    1010
    1111doctestOutputChecker = OutputChecker()
    1212
     13class DjangoTestRunner(unittest.TextTestRunner):
     14   
     15    def __init__(self, verbosity=0, failfast=False, **kwargs):
     16        super(DjangoTestRunner, self).__init__(verbosity=verbosity, **kwargs)
     17        self.failfast = failfast
     18       
     19    def _makeResult(self):
     20        result = super(DjangoTestRunner, self)._makeResult()
     21        failfast = self.failfast
     22       
     23        def stoptest_override(func):
     24            def stoptest(test):
     25                if failfast and not result.wasSuccessful():
     26                    result.stop()
     27                func(test)
     28            return stoptest
     29       
     30        setattr(result, 'stopTest', stoptest_override(result.stopTest))
     31        return result
     32
    1333def get_tests(app_module):
    1434    try:
    1535        app_path = app_module.__name__.split('.')[:-1]
     
    146166        bins[0].addTests(bins[i+1])
    147167    return bins[0]
    148168
    149 def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[]):
     169def run_tests(test_labels, verbosity=1, interactive=True, failfast=False, extra_tests=[]):
    150170    """
    151171    Run the unit tests for all the test labels in the provided list.
    152172    Labels must be of the form:
     
    189209    old_name = settings.DATABASE_NAME
    190210    from django.db import connection
    191211    connection.creation.create_test_db(verbosity, autoclobber=not interactive)
    192     result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
     212    result = DjangoTestRunner(verbosity=verbosity, failfast=failfast).run(suite)
    193213    connection.creation.destroy_test_db(old_name, verbosity)
    194214
    195215    teardown_test_environment()
  • django/core/management/commands/test.py

     
    66    option_list = BaseCommand.option_list + (
    77        make_option('--noinput', action='store_false', dest='interactive', default=True,
    88            help='Tells Django to NOT prompt the user for input of any kind.'),
     9        make_option('--failfast', action='store_true', dest='failfast', default=False,
     10            help='Tells Django to stop running the test suite after first failed test.')
    911    )
    1012    help = 'Runs the test suite for the specified applications, or the entire site if no apps are specified.'
    1113    args = '[appname ...]'
     
    1517    def handle(self, *test_labels, **options):
    1618        from django.conf import settings
    1719        from django.test.utils import get_runner
    18 
     20       
    1921        verbosity = int(options.get('verbosity', 1))
    2022        interactive = options.get('interactive', True)
     23        failfast = options.get('failfast', True)
    2124        test_runner = get_runner(settings)
    2225
    23         failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive)
     26        # Some custom test runners won't accept the failfast flag, so let's make sure they accept it before passing it to them
     27        if 'failfast' in test_runner.func_code.co_varnames:
     28            failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive,
     29                                   failfast=failfast)
     30        else:
     31            failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive)
     32
    2433        if failures:
    2534            sys.exit(failures)
  • tests/regressiontests/test_runner/tests.py

     
     1"""
     2Tests for django test runner
     3"""
     4import StringIO
     5import unittest
     6import django
     7from django.test import TestCase, TransactionTestCase, simple
     8
     9class DjangoTestRunnerTests(TestCase):
     10   
     11    def test_failfast(self):
     12        class MockTestOne(TransactionTestCase):
     13            def runTest(self):
     14                assert False
     15        class MockTestTwo(TransactionTestCase):
     16            def runTest(self):
     17                assert False
     18               
     19        suite = unittest.TestSuite([MockTestOne(), MockTestTwo()])
     20        mock_stream = StringIO.StringIO()
     21        dtr = simple.DjangoTestRunner(verbosity=0, failfast=False, stream=mock_stream)
     22        result = dtr.run(suite)
     23        self.assertEqual(2, result.testsRun)
     24        self.assertEqual(2, len(result.failures))
     25       
     26        dtr = simple.DjangoTestRunner(verbosity=0, failfast=True, stream=mock_stream)
     27        result = dtr.run(suite)
     28        self.assertEqual(1, result.testsRun)
     29        self.assertEqual(1, len(result.failures))
  • tests/runtests.py

     
    8686        self.assert_(not unexpected, "Unexpected Errors: " + '\n'.join(unexpected))
    8787        self.assert_(not missing, "Missing Errors: " + '\n'.join(missing))
    8888
    89 def django_tests(verbosity, interactive, test_labels):
     89def django_tests(verbosity, interactive, failfast, test_labels):
    9090    from django.conf import settings
    9191
    9292    old_installed_apps = settings.INSTALLED_APPS
     
    160160        settings.TEST_RUNNER = 'django.test.simple.run_tests'
    161161    test_runner = get_runner(settings)
    162162
    163     failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive, extra_tests=extra_tests)
     163    failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive, failfast=failfast,
     164                           extra_tests=extra_tests)
    164165    if failures:
    165166        sys.exit(failures)
    166167
     
    182183        help='Verbosity level; 0=minimal output, 1=normal output, 2=all output')
    183184    parser.add_option('--noinput', action='store_false', dest='interactive', default=True,
    184185        help='Tells Django to NOT prompt the user for input of any kind.')
     186    parser.add_option('--failfast', action='store_true', dest='failfast', default=False,
     187        help='Tells Django to stop running the test suite after first failed test.')
    185188    parser.add_option('--settings',
    186189        help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
    187190    options, args = parser.parse_args()
     
    190193    elif "DJANGO_SETTINGS_MODULE" not in os.environ:
    191194        parser.error("DJANGO_SETTINGS_MODULE is not set in the environment. "
    192195                      "Set it or use --settings.")
    193     django_tests(int(options.verbosity), options.interactive, args)
     196    django_tests(int(options.verbosity), options.interactive, options.failfast, args)
  • docs/ref/django-admin.txt

     
    696696Runs tests for all installed models. See :ref:`topics-testing` for more
    697697information.
    698698
     699--failfast
     700~~~~~~~~
     701
     702Use the ``--failfast`` option to stop running tests and report the failure
     703immediately after a test fails.
     704
    699705testserver <fixture fixture ...>
    700706--------------------------------
    701707
Back to Top