diff --git a/django/test/simple.py b/django/test/simple.py index 5f7f86f220..9730a0df1d 100644 --- a/django/test/simple.py +++ b/django/test/simple.py @@ -14,15 +14,19 @@ def build_suite(app_module): "Create a complete Django test suite for the provided application module" suite = unittest.TestSuite() - # Load unit and doctests in the models.py file - suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(app_module)) - try: - suite.addTest(doctest.DocTestSuite(app_module, - checker=doctestOutputChecker, - runner=DocTestRunner)) - except ValueError: - # No doc tests in models.py - pass + # Load unit and doctests in the models.py module. If module has + # a suite() method, use it. Otherwise build the test suite ourselves. + if hasattr(app_module, 'suite'): + suite.addTest(app_module.suite()) + else: + suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(app_module)) + try: + suite.addTest(doctest.DocTestSuite(app_module, + checker=doctestOutputChecker, + runner=DocTestRunner)) + except ValueError: + # No doc tests in models.py + pass # Check to see if a separate 'tests' module exists parallel to the # models module @@ -30,14 +34,19 @@ def build_suite(app_module): app_path = app_module.__name__.split('.')[:-1] test_module = __import__('.'.join(app_path + [TEST_MODULE]), {}, {}, TEST_MODULE) - suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_module)) - try: - suite.addTest(doctest.DocTestSuite(test_module, - checker=doctestOutputChecker, - runner=DocTestRunner)) - except ValueError: - # No doc tests in tests.py - pass + # Load unit and doctests in the tests.py module. If module has + # a suite() method, use it. Otherwise build the test suite ourselves. + if hasattr(test_module, 'suite'): + suite.addTest(test_module.suite()) + else: + suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_module)) + try: + suite.addTest(doctest.DocTestSuite(test_module, + checker=doctestOutputChecker, + runner=DocTestRunner)) + except ValueError: + # No doc tests in tests.py + pass except ImportError, e: # Couldn't import tests.py. Was it due to a missing file, or # due to an import error in a tests.py that actually exists? diff --git a/docs/testing.txt b/docs/testing.txt index 3839c45c01..0d59ad742c 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -118,10 +118,16 @@ An equivalent unittest test case for the above example would look like:: self.assertEquals(self.lion.speak(), 'The lion says "roar"') self.assertEquals(self.cat.speak(), 'The cat says "meow"') -When you `run your tests`_, the test utility will find all the test cases -(that is, subclasses of ``unittest.TestCase``) in ``models.py`` and -``tests.py``, automatically build a test suite out of those test cases, -and run that suite. +When you `run your tests`_, the default behavior of the test utility is +to find all the test cases (that is, subclasses of ``unittest.TestCase``) +in ``models.py`` and ``tests.py``, automatically build a test suite out of +those test cases, and run that suite. + +However, if you define a method called ``suite()`` in either ``models.py`` or +``tests.py``, that method will be used to construct the test suite for that +module. This follows the `suggested organization`_ for unit tests. See the +Python documentation for more details on how to construct a complex test +suite. For more details about ``unittest``, see the `standard library unittest documentation`_. @@ -129,6 +135,7 @@ documentation`_. .. _unittest: http://docs.python.org/lib/module-unittest.html .. _standard library unittest documentation: unittest_ .. _run your tests: `Running tests`_ +.. _suggested organization: http://docs.python.org/lib/organizing-tests.html Which should I use? ------------------- diff --git a/tests/modeltests/test_client/tests.py b/tests/modeltests/test_client/tests.py new file mode 100644 index 0000000000..09f292e037 --- /dev/null +++ b/tests/modeltests/test_client/tests.py @@ -0,0 +1,20 @@ +# Validate that you can override the default test suite + +import unittest + +def suite(): + """ + Define a suite that deliberately ignores a test defined in + this module. + """ + + testSuite = unittest.TestSuite() + testSuite.addTest(SampleTests('testGoodStuff')) + return testSuite + +class SampleTests(unittest.TestCase): + def testGoodStuff(self): + pass + + def testBadStuff(self): + self.fail("This test shouldn't run")