Ticket #2879: django_live_server_1.0.2.diff
File django_live_server_1.0.2.diff, 8.9 KB (added by , 16 years ago) |
---|
-
django/test/testcases.py
1 1 import re 2 2 import unittest 3 import socket 4 import threading 3 5 from urlparse import urlsplit, urlunsplit 4 6 from xml.dom.minidom import parseString, Node 5 7 … … 12 14 from django.test import _doctest as doctest 13 15 from django.test.client import Client 14 16 from django.utils import simplejson 17 from django.core.handlers.wsgi import WSGIHandler 18 from django.core.servers import basehttp 15 19 16 20 normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s) 17 21 … … 169 173 # side effects on other tests. 170 174 transaction.rollback_unless_managed() 171 175 176 class TestServerThread(threading.Thread): 177 """Thread for running a http server while tests are running.""" 178 179 def __init__(self, address, port): 180 self.address = address 181 self.port = port 182 self._stopevent = threading.Event() 183 self.started = threading.Event() 184 self.error = None 185 super(TestServerThread, self).__init__() 186 187 def run(self): 188 """Sets up test server and database and loops over handling http requests.""" 189 try: 190 handler = basehttp.AdminMediaHandler(WSGIHandler()) 191 server_address = (self.address, self.port) 192 httpd = basehttp.StoppableWSGIServer(server_address, basehttp.WSGIRequestHandler) 193 httpd.set_app(handler) 194 self.started.set() 195 except basehttp.WSGIServerException, e: 196 self.error = e 197 self.started.set() 198 return 199 200 # Must do database stuff in this new thread if database in memory. 201 from django.conf import settings 202 if settings.DATABASE_ENGINE == 'sqlite3' \ 203 and (not settings.TEST_DATABASE_NAME or settings.TEST_DATABASE_NAME == ':memory:'): 204 from django.db import connection 205 db_name = connection.creation.create_test_db(0) 206 # Import the fixture data into the test database. 207 if hasattr(self, 'fixtures'): 208 # We have to use this slightly awkward syntax due to the fact 209 # that we're using *args and **kwargs together. 210 call_command('loaddata', *self.fixtures, **{'verbosity': 0}) 211 212 # Loop until we get a stop event. 213 while not self._stopevent.isSet(): 214 httpd.handle_request() 215 216 def join(self, timeout=None): 217 """Stop the thread and wait for it to finish.""" 218 self._stopevent.set() 219 threading.Thread.join(self, timeout) 220 172 221 class TestCase(unittest.TestCase): 173 222 def _pre_setup(self): 174 223 """Performs any pre-test setup. This includes: … … 225 274 settings.ROOT_URLCONF = self._old_root_urlconf 226 275 clear_url_caches() 227 276 277 def start_test_server(self, address='localhost', port=8000): 278 """Creates a live test server object (instance of WSGIServer).""" 279 self.server_thread = TestServerThread(address, port) 280 self.server_thread.start() 281 self.server_thread.started.wait() 282 if self.server_thread.error: 283 raise self.server_thread.error 284 285 def stop_test_server(self): 286 if self.server_thread: 287 self.server_thread.join() 288 228 289 def assertRedirects(self, response, expected_url, status_code=302, 229 290 target_status_code=200, host=None): 230 291 """Asserts that a response redirected to a specific URL, and that the -
django/core/servers/basehttp.py
11 11 import mimetypes 12 12 import os 13 13 import re 14 import socket 14 15 import stat 15 16 import sys 16 17 import urllib … … 669 670 start_response(status, headers.items()) 670 671 return output 671 672 673 class StoppableWSGIServer(WSGIServer): 674 """WSGIServer with short timeout, so that server thread can stop this server.""" 675 676 def server_bind(self): 677 """Sets timeout to 1 second.""" 678 WSGIServer.server_bind(self) 679 self.socket.settimeout(1) 680 681 def get_request(self): 682 """Checks for timeout when getting request.""" 683 try: 684 sock, address = self.socket.accept() 685 sock.settimeout(None) 686 return (sock, address) 687 except socket.timeout: 688 raise 689 672 690 def run(addr, port, wsgi_handler): 673 691 server_address = (addr, port) 674 692 httpd = WSGIServer(server_address, WSGIRequestHandler) -
tests/regressiontests/test_client_regress/models.py
9 9 from django.core.exceptions import SuspiciousOperation 10 10 from django.template import TemplateDoesNotExist, TemplateSyntaxError 11 11 12 import urllib 13 12 14 class AssertContainsTests(TestCase): 13 15 def test_contains(self): 14 16 "Responses can be inspected for content, including counting repeated substrings" … … 354 356 url = reverse('arg_view', args=['somename']) 355 357 self.assertEquals(url, '/test_client_regress/arg_view/somename/') 356 358 359 class TestServerTests(TestCase): 360 def setUp(self): 361 self.start_test_server(address='localhost', port=8001) 362 363 def tearDown(self): 364 self.stop_test_server() 365 366 def test_server_up(self): 367 url = urllib.urlopen('http://localhost:8001') 368 self.assertEqual(url.read(), 'Django Internal Tests: 404 Error') 369 url.close() 370 371 def test_serve_page(self): 372 url = urllib.urlopen('http://localhost:8001/accounts/login') 373 # Just make sure this isn't a 404, and we've gotten something. 374 self.assertNotEqual(url.read(), 'Django Internal Tests: 404 Error') 375 url.close() 376 357 377 class SessionTests(TestCase): 358 378 fixtures = ['testdata.json'] 359 379 … … 382 402 response = self.client.get('/test_client_regress/check_session/') 383 403 self.assertEqual(response.status_code, 200) 384 404 self.assertEqual(response.content, 'YES') 385 386 No newline at end of file 405 -
AUTHORS
290 290 Robert Myers <myer0052@gmail.com> 291 291 Nebojša Dorđević 292 292 Doug Napoleone <doug@dougma.com> 293 Devin Naquin <dnaquin@gmail.com> 293 294 Gopal Narayanan <gopastro@gmail.com> 294 295 Fraser Nevett <mail@nevett.org> 295 296 Sam Newman <http://www.magpiebrain.com/> -
docs/topics/testing.txt
867 867 868 868 .. _emptying-test-outbox: 869 869 870 Running tests with a live test server 871 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 872 873 **New in Django development version** 874 875 When running tests that use in-browser frameworks such as Twille_ and 876 Selenium_, it's necessary to have a running test server. Django's custom 877 ``TestCase`` class supports starting a live server for these purposes. 878 879 ``start_test_server(address='localhost', port=8000)`` 880 Starts a test server at ``address`` on ``port``. This should be done in the 881 ``setUp()`` method of a subclass of ``TestCase``. The server then can be 882 accessed at http://address:port. 883 884 ``stop_test_server()`` 885 Stops the test server that was started with ``start_test_server``. This 886 must be done before ``start_test_server`` can be called again, so this 887 should be done in the ``tearDown()`` method of a subclass of ``TestCase``. 888 889 This can be used to start a server that can then be accessed by Twill, Selenium 890 or another in-browser test framework. For example:: 891 892 from django.test.testcases import TestCase 893 from selenium import selenium 894 895 class TestLogin(TestCase): 896 fixtures = ['login_info.xml'] 897 898 def setUp(self): 899 # Start a test server and tell selenium where to find it. 900 self.start_test_server('localhost', 8000) 901 self.selenium = selenium('localhost', 4444, \ 902 '*pifirefox', 'http://localhost:8000') 903 904 def tearDown(self): 905 # Stop server and Selenium 906 self.selenium.stop() 907 self.stop_test_server() 908 909 def testLogin(self): 910 self.selenium.open('/admin/') 911 self.selenium.type('username', 'admin') 912 self.selenium.type('password', 'password') 913 self.selenium.click("//input[@value='Log in']") 914 915 .. _Twill: http://twill.idyll.org/ 916 .. _Selenium: http://www.openqa.org/selenium/ 917 870 918 Emptying the test outbox 871 919 ~~~~~~~~~~~~~~~~~~~~~~~~ 872 920