I found some time this evening to work this out, and have included a revised patch for this proposal at the end of this message.
I tried to keep changes to an absolute minimum, but here are a few notes about the changes and decisions I did make: * The addition of this feature required what I imagine to be a significant change to test suite runner. Namely, I switched the order of the build_suite() and setup_test_environment() methods in run_tests(). The reason for this has to do with what i suggested in my earlier reply in this thread, namely that there isn't a feasible way to connect to the signals from application code until after applications have been imported. I also wanted to attempt to implement Russ's suggestion of having Django itself use the signals for setup and teardown. The most logical and clean way to do this (and the only way to organize things such that Django could use the code) was to construct the run_test() sequence such that test suites are first built, then setup, then run tests, then teardown. The Django tests suite passed when the order was inverted, but I am quite certain it is a huge assumption on my part that the order can be switched here. Does anybody have any opinions on this, or reasonings as to why the setup_test_environment() stuff would need to be called before build_suite()? I imagine this would be the greatest concern with my proposed patch. * The test utility methods setup_test_environment() and teardown_test_environment() are now connected to the respective signals and are executed when those emit, rather than being called directly from the test suite runner. The **kwargs was added to their signature so that the they could be executed via the signal. * Aside from adding the code to create the signals and to emit them in the test runner, that's all the changes that were necessary to implement this feature. * I have included documentation changes in the patch in what is hopefully a tolerable first stab. I welcome any additional feedback or suggestions. Provided there are no serious objections or deal breakers pointed out in this discussion, I'll submit a ticket for this, which I assume is the best way to move it forward in the official discussion and review process. Here's my revised proposed patch: Index: django/test/simple.py =================================================================== --- django/test/simple.py (revision 13861) +++ django/test/simple.py (working copy) @@ -7,6 +7,7 @@ from django.test import _doctest as doctest from django.test.utils import setup_test_environment, teardown_test_environment from django.test.testcases import OutputChecker, DocTestRunner, TestCase +from django.test.signals import test_setup, test_teardown # The module name for tests outside models.py TEST_MODULE = 'tests' @@ -230,7 +231,7 @@ self.failfast = failfast def setup_test_environment(self, **kwargs): - setup_test_environment() + test_setup.send(sender=self) settings.DEBUG = False def build_suite(self, test_labels, extra_tests=None, **kwargs): @@ -284,7 +285,7 @@ connection.creation.destroy_test_db(old_name, self.verbosity) def teardown_test_environment(self, **kwargs): - teardown_test_environment() + test_teardown.send(sender=self) def suite_result(self, suite, result, **kwargs): return len(result.failures) + len(result.errors) @@ -308,8 +309,8 @@ Returns the number of tests that failed. """ + suite = self.build_suite(test_labels, extra_tests) self.setup_test_environment() - suite = self.build_suite(test_labels, extra_tests) old_config = self.setup_databases() result = self.run_suite(suite) self.teardown_databases(old_config) Index: django/test/signals.py =================================================================== --- django/test/signals.py (revision 13861) +++ django/test/signals.py (working copy) @@ -1,3 +1,5 @@ from django.dispatch import Signal template_rendered = Signal(providing_args=["template", "context"]) +test_setup = Signal() +test_teardown = Signal() \ No newline at end of file Index: django/test/utils.py =================================================================== --- django/test/utils.py (revision 13861) +++ django/test/utils.py (working copy) @@ -52,7 +52,7 @@ return self.nodelist.render(context) -def setup_test_environment(): +def setup_test_environment(**kwargs): """Perform any global pre-test setup. This involves: - Installing the instrumented test renderer @@ -71,8 +71,9 @@ mail.outbox = [] deactivate() +signals.test_setup.connect(setup_test_environment) -def teardown_test_environment(): +def teardown_test_environment(**kwargs): """Perform any global post-test teardown. This involves: - Restoring the original test renderer @@ -89,6 +90,7 @@ del mail.original_email_backend del mail.outbox +signals.test_teardown.connect(teardown_test_environment) def get_runner(settings): test_path = settings.TEST_RUNNER.split('.') Index: docs/ref/signals.txt =================================================================== --- docs/ref/signals.txt (revision 13861) +++ docs/ref/signals.txt (working copy) @@ -455,6 +455,39 @@ The :class:`~django.template.Context` with which the template was rendered. +test_setup +---------- + +.. data:: django.test.signals.test_setup + :module: + +.. versionadded:: 1.3 + +Sent during global pre-test setup, just after applications have loaded and +the test suite has been built. This signal is not emitted during normal +operation. + +Arguments sent with this signal: + + sender + The :class:`~django.test.simple.DjangoTestSuiteRunner` object. + +test_teardown +------------- + +.. data:: django.test.signals.test_teardown + :module: + +.. versionadded:: 1.3 + +Sent during global post-test breakdown. This signal is not emitted during +normal operation. + +Arguments sent with this signal: + + sender + The :class:`~django.test.simple.DjangoTestSuiteRunner` object. + Database Wrappers ================= -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.