To use a specific url-config in your Django tests all you have to do is specify it:
class MyTests(TestCase):
urls = 'myproj.myapp.urls'
def test_myurl(self):
r = self.client.get('/foo/') # looks up /foo/ in myproj/myapp/urls.py
it doesn’t look like the implementation is thread-safe however:
def _urlconf_setup(self):
if hasattr(self, 'urls'):
self._old_root_urlconf = settings.ROOT_URLCONF
settings.ROOT_URLCONF = self.urls
clear_url_caches()
and I’m seeing 404 errors in my test-log after I run the test-suite with py.test -n8 (using all 8 cpus).
Has anyone else seen/solved this problem?
The short answer: setting
urlson yourTestCasesubclass is not thread safe when calledfrom py.test -n, presumably because the different threads are clobberingsettings.ROOT_URLCONF.There is code in
django/core/handlers/base.py:get_response()(I just checked the latest revision too) which will fetch urlconf from the request object if present, instead of usingsettings.ROOT_URLCONF.The solution then, is to attach the value of
self.urlsto therequestobject thatClient.pypasses to the view function. We haven’t seen any problems after implementing this fix, running 1100+ tests with-n8.(If you already have your own copies of
client.pyandtestcases.py, it is relatively easy (~14 loc) to remove the current urlconf machinery from_pre_setupand instead passself.urlsthrough Client so ClientHandler can attach it torequestbefore callingself.get_response().)