diff options
| author | Kevin Kubasik <kevin@kubasik.net> | 2009-06-23 07:02:54 +0000 |
|---|---|---|
| committer | Kevin Kubasik <kevin@kubasik.net> | 2009-06-23 07:02:54 +0000 |
| commit | e223716bd80ced8a2ca25ea4befc327f425c7203 (patch) | |
| tree | ca94bc45308801ba77d984c51bf5fcebb5d29f1d /django | |
| parent | 2fd60f00163e59bcd87350598af3029f7af5b2a3 (diff) | |
[gsoc2009-testing] Initial tests for the Admin views based on exisiting models and fixtures. runtest.py --windmill will activate them
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/test-improvements@11087 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rw-r--r-- | django/conf/global_settings.py | 2 | ||||
| -rw-r--r-- | django/core/management/commands/test_windmill.py | 10 | ||||
| -rw-r--r-- | django/test/test_coverage.py | 13 | ||||
| -rw-r--r-- | django/test/windmill_tests.py | 123 | ||||
| -rw-r--r-- | django/utils/module_tools/__init__.py | 16 |
5 files changed, 141 insertions, 23 deletions
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 431b5208b8..eb9629990d 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -398,7 +398,7 @@ TEST_DATABASE_COLLATION = None # Specify the coverage test runner -COVERAGE_TEST_RUNNER = 'django.test.test_coverage.BaseCoverageRunner' +COVERAGE_TEST_RUNNER = 'django.test.test_coverage.ConsoleReportCoverageRunner' # Specify regular expressions of code blocks the coverage analyzer should # ignore as statements (e.g. ``raise NotImplemented``). diff --git a/django/core/management/commands/test_windmill.py b/django/core/management/commands/test_windmill.py index d9b72f9c3e..406083c739 100644 --- a/django/core/management/commands/test_windmill.py +++ b/django/core/management/commands/test_windmill.py @@ -1,5 +1,6 @@ from django.core.management.base import BaseCommand -from windmill.authoring import djangotest +#from windmill.authoring import djangotest +from django.test import windmill_tests as djangotest import sys, os from time import sleep import types @@ -18,7 +19,10 @@ def attempt_import(name, suffix): s = name.split('.') mod = __import__(s.pop(0)) for x in s+[suffix]: - mod = getattr(mod, x) + try: + mod = getattr(mod, x) + except Exception, e: + pass return mod class Command(BaseCommand): @@ -31,7 +35,7 @@ class Command(BaseCommand): def handle(self, *labels, **options): from windmill.conf import global_settings - from windmill.authoring.djangotest import WindmillDjangoUnitTest + from django.test.windmill_tests import WindmillDjangoUnitTest if 'ie' in labels: global_settings.START_IE = True sys.argv.remove('ie') diff --git a/django/test/test_coverage.py b/django/test/test_coverage.py index cf35795ee5..f6cf0312ac 100644 --- a/django/test/test_coverage.py +++ b/django/test/test_coverage.py @@ -63,6 +63,15 @@ class BaseCoverageRunner(object): coverage_modules, getattr(settings, 'COVERAGE_MODULE_EXCLUDES', []), getattr(settings, 'COVERAGE_PATH_EXCLUDES', [])) + + + return results + +class ConsoleReportCoverageRunner(BaseCoverageRunner): + + def run_tests(self, *args, **kwargs): + """docstring for run_tests""" + res = super(ConsoleReportCoverageRunner, self).run_tests( *args, **kwargs) self.cov.report(self.modules.values(), show_missing=1) if self.excludes: @@ -77,9 +86,7 @@ class BaseCoverageRunner(object): for e in self.errors: print >> sys.stderr, e, print >> sys.stdout - - return results - + return res class ReportingCoverageRunner(BaseCoverageRunner): """Runs coverage.py analysis, as well as generating detailed HTML reports.""" diff --git a/django/test/windmill_tests.py b/django/test/windmill_tests.py new file mode 100644 index 0000000000..569f13a014 --- /dev/null +++ b/django/test/windmill_tests.py @@ -0,0 +1,123 @@ + +# Code from django_live_server_r8458.diff @ http://code.djangoproject.com/ticket/2879#comment:41 +# Editing to monkey patch django rather than be in trunk + +import socket +import threading +from django.core.handlers.wsgi import WSGIHandler +from django.core.servers import basehttp +from django.test.testcases import call_command + +#from django.core.management import call_command + +# support both django 1.0 and 1.1 +try: + from django.test.testcases import TransactionTestCase as TestCase +except ImportError: + from django.test.testcases import TestCase + +class StoppableWSGIServer(basehttp.WSGIServer): + """WSGIServer with short timeout, so that server thread can stop this server.""" + + def server_bind(self): + """Sets timeout to 1 second.""" + basehttp.WSGIServer.server_bind(self) + self.socket.settimeout(1) + + def get_request(self): + """Checks for timeout when getting request.""" + try: + sock, address = self.socket.accept() + sock.settimeout(None) + return (sock, address) + except socket.timeout: + raise + +class TestServerThread(threading.Thread): + """Thread for running a http server while tests are running.""" + + def __init__(self, address, port): + self.address = address + self.port = port + self._stopevent = threading.Event() + self.started = threading.Event() + self.error = None + super(TestServerThread, self).__init__() + + def run(self): + """Sets up test server and database and loops over handling http requests.""" + try: + handler = basehttp.AdminMediaHandler(WSGIHandler()) + httpd = None + while httpd is None: + try: + server_address = (self.address, self.port) + httpd = StoppableWSGIServer(server_address, basehttp.WSGIRequestHandler) + except basehttp.WSGIServerException, e: + if "Address already in use" in str(e): + self.port +=1 + else: + raise e + httpd.set_app(handler) + self.started.set() + except basehttp.WSGIServerException, e: + self.error = e + self.started.set() + return + + # Must do database stuff in this new thread if database in memory. + from django.conf import settings + if settings.DATABASE_ENGINE == 'sqlite3' \ + and (not settings.TEST_DATABASE_NAME or settings.TEST_DATABASE_NAME == ':memory:'): + from django.db import connection + db_name = connection.creation.create_test_db(0) + # Import the fixture data into the test database. + if hasattr(self, 'fixtures'): + # We have to use this slightly awkward syntax due to the fact + # that we're using *args and **kwargs together. + call_command('loaddata', *self.fixtures, **{'verbosity': 0}) + + # Loop until we get a stop event. + while not self._stopevent.isSet(): + httpd.handle_request() + httpd.server_close() + + def join(self, timeout=None): + """Stop the thread and wait for it to finish.""" + self._stopevent.set() + threading.Thread.join(self, timeout) + + +def start_test_server(self, address='localhost', port=8000): + """Creates a live test server object (instance of WSGIServer).""" + self.server_thread = TestServerThread(address, port) + if hasattr(self, 'fixtures'): + self.server_thread.__setattr__('fixtures', self.fixtures) + self.server_thread.start() + self.server_thread.started.wait() + if self.server_thread.error: + raise self.server_thread.error + +def stop_test_server(self): + if self.server_thread: + self.server_thread.join() + +## New Code + +TestCase.start_test_server = classmethod(start_test_server) +TestCase.stop_test_server = classmethod(stop_test_server) + +from windmill.authoring import unit + +class WindmillDjangoUnitTest(TestCase, unit.WindmillUnitTestCase): + test_port = 8000 + def setUp(self): + self.start_test_server('localhost', self.test_port) + self.test_url = 'http://localhost:%d' % self.server_thread.port + unit.WindmillUnitTestCase.setUp(self) + + def tearDown(self): + unit.WindmillUnitTestCase.tearDown(self) + self.stop_test_server() + +WindmillDjangoTransactionUnitTest = WindmillDjangoUnitTest diff --git a/django/utils/module_tools/__init__.py b/django/utils/module_tools/__init__.py index d940906d2d..976d4b5e4f 100644 --- a/django/utils/module_tools/__init__.py +++ b/django/utils/module_tools/__init__.py @@ -1,19 +1,3 @@ -""" -Copyright 2009 55 Minutes (http://www.55minutes.com) - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - from module_loader import * from module_walker import * |
