Commit 4ba37384 authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #16534 -- Improved ability to customize DiscoverRunner

Added DiscoverRunner.test_suite and .test_runner attributes.

Thanks tomchristie for the suggestion and jcd for the patch.
parent fca4c482
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ class DiscoverRunner(object):
    A Django test runner that uses unittest2 test discovery.
    """

    test_suite = TestSuite
    test_runner = unittest.TextTestRunner
    test_loader = defaultTestLoader
    reorder_by = (TestCase, )
    option_list = (
@@ -42,7 +44,7 @@ class DiscoverRunner(object):
        unittest.installHandler()

    def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
        suite = TestSuite()
        suite = self.test_suite()
        test_labels = test_labels or ['.']
        extra_tests = extra_tests or []

@@ -107,7 +109,7 @@ class DiscoverRunner(object):
        return setup_databases(self.verbosity, self.interactive, **kwargs)

    def run_suite(self, suite, **kwargs):
        return unittest.TextTestRunner(
        return self.test_runner(
            verbosity=self.verbosity,
            failfast=self.failfast,
        ).run(suite)
@@ -201,7 +203,8 @@ def reorder_suite(suite, classes):
    classes[1], etc. Tests with no match in classes are placed last.
    """
    class_count = len(classes)
    bins = [unittest.TestSuite() for i in range(class_count+1)]
    suite_class = type(suite)
    bins = [suite_class() for i in range(class_count+1)]
    partition_suite(suite, classes, bins)
    for i in range(class_count):
        bins[0].addTests(bins[i+1])
@@ -218,8 +221,9 @@ def partition_suite(suite, classes, bins):
    Tests of type classes[i] are added to bins[i],
    tests with no match found in classes are place in bins[-1]
    """
    suite_class = type(suite)
    for test in suite:
        if isinstance(test, unittest.TestSuite):
        if isinstance(test, suite_class):
            partition_suite(test, classes, bins)
        else:
            for i in range(len(classes)):
+8 −0
Original line number Diff line number Diff line
@@ -285,6 +285,14 @@ Templates
* ``TypeError`` exceptions are not longer silenced when raised during the
  rendering of a template.

Tests
^^^^^

* :class:`~django.test.runner.DiscoverRunner` has two new attributes,
  :attr:`~django.test.runner.DiscoverRunner.test_suite` and
  :attr:`~django.test.runner.DiscoverRunner.test_runner`, which facilitate
  overriding the way tests are collected and run.

Backwards incompatible changes in 1.7
=====================================

+19 −0
Original line number Diff line number Diff line
@@ -338,6 +338,25 @@ execute and tear down the test suite.
Attributes
~~~~~~~~~~

.. attribute:: DiscoverRunner.test_suite

    .. versionadded:: 1.7

    The class used to build the test suite. By default it is set to
    ``unittest.TestSuite``. This can be overridden if you wish to implement
    different logic for collecting tests.

.. attribute:: DiscoverRunner.test_runner

    .. versionadded:: 1.7

    This is the class of the low-level test runner which is used to execute
    the individual tests and format the results. By default it is set to
    ``unittest.TextTestRunner``. Despite the unfortunate similarity in
    naming conventions, this is not the same type of class as
    ``DiscoverRunner``, which covers a broader set of responsibilites. You
    can override this attribute to modify the way tests are run and reported.

.. attribute:: DiscoverRunner.test_loader

    This is the class that loads tests, whether from TestCases or modules or
+10 −1
Original line number Diff line number Diff line
from contextlib import contextmanager
import os
import sys
from unittest import expectedFailure
from unittest import expectedFailure, TestSuite, TextTestRunner, defaultTestLoader

from django.test import TestCase
from django.test.runner import DiscoverRunner
@@ -68,3 +68,12 @@ class DiscoverRunnerTest(TestCase):
            ).countTestCases()

        self.assertEqual(count, 3)

    def test_overrideable_test_suite(self):
        self.assertEqual(DiscoverRunner().test_suite, TestSuite)

    def test_overrideable_test_runner(self):
        self.assertEqual(DiscoverRunner().test_runner, TextTestRunner)

    def test_overrideable_test_loader(self):
        self.assertEqual(DiscoverRunner().test_loader, defaultTestLoader)