Ticket #16185: 16185_15675.diff

File 16185_15675.diff, 9.3 KB (added by Dmitry Jemerov, 13 years ago)

Attached patch fixes this ticket along with ticket #15675 (it touches the same code so it's easier to fix both in the same patch)

  • AUTHORS

     
    535535    Cheng Zhang
    536536    Zlatko Mašek <zlatko.masek@gmail.com>
    537537    Ryan Niemeyer <https://profiles.google.com/ryan.niemeyer/about>
     538    Mikołaj Siedlarek <mikolaj.siedlarek@gmail.com>
     539    Dmitry Jemerov <intelliyole@gmail.com>
    538540
    539541A big THANK YOU goes to:
    540542
  • docs/topics/testing.txt

     
    17441744    write your own test runner, ensure accept and handle the ``**kwargs``
    17451745    parameter.
    17461746
     1747    .. versionadded:: 1.4
     1748
     1749    Your test runner may define some command-line options which will be fed
     1750    into the ``OptionParser`` of ``test`` management command. If you need such
     1751    functionality, see the ``option_list`` attribute. Options you declare
     1752    will be provided to your test runner's constructor as additional keyword
     1753    arguments.
     1754
     1755Attributes
     1756~~~~~~~~~~
     1757
     1758.. versionadded:: 1.4
     1759
     1760.. attribute:: DjangoTestSuiteRunner.option_list
     1761
     1762    This is the tuple of ``optparse`` options which will be fed into the management
     1763    command's ``OptionParser`` for parsing arguments.
     1764
     1765Methods
     1766~~~~~~~
     1767
    17471768.. method:: DjangoTestSuiteRunner.run_tests(test_labels, extra_tests=None, **kwargs)
    17481769
    17491770    Run the test suite.
  • docs/ref/django-admin.txt

     
    964964Use the :djadminopt:`--failfast` option to stop running tests and report the failure
    965965immediately after a test fails.
    966966
     967.. versionadded:: 1.4
     968.. django-admin-option:: --testrunner
     969
     970The :djandminopt:`--testrunner` option can be used to override the test runner class
     971specified by the :setting:`TEST_RUNNER` setting.
     972
    967973testserver <fixture fixture ...>
    968974--------------------------------
    969975
  • django/test/utils.py

     
    118118    warnings.filters = state[:]
    119119
    120120
    121 def get_runner(settings):
    122     test_path = settings.TEST_RUNNER.split('.')
     121def get_runner(settings, test_runner_class=None):
     122    if not test_runner_class:
     123        test_runner_class = settings.TEST_RUNNER
     124
     125    test_path = test_runner_class.split('.')
    123126    # Allow for Python 2.5 relative paths
    124127    if len(test_path) > 1:
    125128        test_module_name = '.'.join(test_path[:-1])
  • django/core/management/commands/test.py

     
     1from django.conf import settings
    12from django.core.management.base import BaseCommand
    2 from optparse import make_option
     3from optparse import make_option, OptionParser
    34import sys
     5from django.test.utils import get_runner
    46
    57class Command(BaseCommand):
    68    option_list = BaseCommand.option_list + (
    79        make_option('--noinput', action='store_false', dest='interactive', default=True,
    810            help='Tells Django to NOT prompt the user for input of any kind.'),
    911        make_option('--failfast', action='store_true', dest='failfast', default=False,
    10             help='Tells Django to stop running the test suite after first failed test.')
     12            help='Tells Django to stop running the test suite after first failed test.'),
     13        make_option('--testrunner', action='store', dest='testrunner',
     14            help='Tells Django to use specified test runner class instead of the one '+
     15                 'specified by the TEST_RUNNER setting.')
    1116    )
    1217    help = 'Runs the test suite for the specified applications, or the entire site if no apps are specified.'
    1318    args = '[appname ...]'
    1419
    1520    requires_model_validation = False
    1621
     22    def run_from_argv(self, argv):
     23        """
     24        Pre-parse the command line to extract the value of the --testrunner
     25        option. This allows a test runner to define additional command line
     26        arguments.
     27        """
     28        self.test_runner = None
     29        option = '--testrunner='
     30        for arg in argv[2:]:
     31            if arg.startswith(option):
     32                self.test_runner = arg[len(option):]
     33                break
     34        super(Command, self).run_from_argv(argv)
     35
     36    def create_parser(self, prog_name, subcommand):
     37        test_runner_class = get_runner(settings, self.test_runner)
     38        options = self.option_list + getattr(test_runner_class, 'option_list', ())
     39        return OptionParser(prog=prog_name,
     40                            usage=self.usage(subcommand),
     41                            version=self.get_version(),
     42                            option_list=options)
     43
    1744    def handle(self, *test_labels, **options):
    1845        from django.conf import settings
    1946        from django.test.utils import get_runner
    2047
    21         verbosity = int(options.get('verbosity', 1))
    22         interactive = options.get('interactive', True)
    23         failfast = options.get('failfast', False)
    24         TestRunner = get_runner(settings)
     48        TestRunner = get_runner(settings, options.get('testrunner'))
     49        options['verbosity'] = int(options.get('verbosity', 1))
     50        options.setdefault('interactive', True)
     51        options.setdefault('failfast', False)
    2552
    26         test_runner = TestRunner(verbosity=verbosity, interactive=interactive, failfast=failfast)
     53        test_runner = TestRunner(**options)
    2754        failures = test_runner.run_tests(test_labels)
    2855
    2956        if failures:
  • tests/regressiontests/test_runner/tests.py

     
    22Tests for django test runner
    33"""
    44import StringIO
     5from optparse import make_option
    56import warnings
    67
    78from django.core.exceptions import ImproperlyConfigured
     9from django.core.management import call_command
    810from django.test import simple
    911from django.test.utils import get_warnings_state, restore_warnings_state
    1012from django.utils import unittest
     13from regressiontests.admin_scripts.tests import AdminScriptTestCase
    1114
    1215
    1316class DjangoTestRunnerTests(unittest.TestCase):
     
    128131
    129132        self.assertRaises(ImproperlyConfigured, simple.dependency_ordered, raw, dependencies=dependencies)
    130133
     134
     135class MockTestRunner(object):
     136    invoked = False
     137
     138    def __init__(self, *args, **kwargs):
     139        pass
     140   
     141    def run_tests(self, test_labels, extra_tests=None, **kwargs):
     142        MockTestRunner.invoked = True
     143
     144
     145class ManageCommandTests(unittest.TestCase):
     146
     147    def test_custom_test_runner(self):
     148        call_command('test', 'sites',
     149                     testrunner='regressiontests.test_runner.tests.MockTestRunner')
     150        self.assertTrue(MockTestRunner.invoked,
     151                        "The custom test runner has not been invoked")
     152
     153
     154class CustomOptionsTestRunner(simple.DjangoTestSuiteRunner):
     155    option_list = (
     156        make_option('--option_a','-a', action='store', dest='option_a', default='1'),
     157        make_option('--option_b','-b', action='store', dest='option_b', default='2'),
     158        make_option('--option_c','-c', action='store', dest='option_c', default='3'),
     159    )
     160
     161    def __init__(self, verbosity=1, interactive=True, failfast=True, option_a=None, option_b=None, option_c=None, **kwargs):
     162        super(CustomOptionsTestRunner, self).__init__(verbosity=verbosity, interactive=interactive,
     163                                                      failfast=failfast)
     164        self.option_a = option_a
     165        self.option_b = option_b
     166        self.option_c = option_c
     167
     168    def run_tests(self, test_labels, extra_tests=None, **kwargs):
     169        print "%s:%s:%s" % (self.option_a, self.option_b, self.option_c)
     170
     171
     172class CustomTestRunnerOptionsTests(AdminScriptTestCase):
     173
     174    def setUp(self):
     175        settings = {
     176            'TEST_RUNNER': '\'regressiontests.test_runner.tests.CustomOptionsTestRunner\'',
     177        }
     178        self.write_settings('settings.py', sdict=settings)
     179
     180    def tearDown(self):
     181        self.remove_settings('settings.py')
     182
     183    def test_default_options(self):
     184        args = ['test', '--settings=settings']
     185        out, err = self.run_django_admin(args)
     186        self.assertNoOutput(err)
     187        self.assertOutput(out, '1:2:3')
     188
     189    def test_default_and_given_options(self):
     190        args = ['test', '--settings=settings', '--option_b=foo']
     191        out, err = self.run_django_admin(args)
     192        self.assertNoOutput(err)
     193        self.assertOutput(out, '1:foo:3')
     194
     195    def test_option_name_and_value_separated(self):
     196        args = ['test', '--settings=settings', '--option_b', 'foo']
     197        out, err = self.run_django_admin(args)
     198        self.assertNoOutput(err)
     199        self.assertOutput(out, '1:foo:3')
     200
     201    def test_all_options_given(self):
     202        args = ['test', '--settings=settings', '--option_a=bar', '--option_b=foo', '--option_c=31337']
     203        out, err = self.run_django_admin(args)
     204        self.assertNoOutput(err)
     205        self.assertOutput(out, 'bar:foo:31337')
Back to Top