Opened 11 years ago
Closed 11 years ago
#21466 closed Bug (invalid)
override_settings(LOGIN_URL=…) does not work when not first test
Reported by: | Jannis Vajen | Owned by: | nobody |
---|---|---|---|
Component: | Testing framework | Version: | 1.6 |
Severity: | Normal | Keywords: | settings |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Overriding LOGIN_URL
in the tests does not work when another test is run beforehand.
from django.test import TestCase from django.test.utils import override_settings from django.core.urlresolvers import reverse from django.conf import settings class OverrideSettingsTest(TestCase): def test_a(self): """ Toggle this test by commenting it out and see whether test_b() passes. """ response = self.client.get(reverse("harmless-view")) self.assertEqual(response.status_code, 301) @override_settings(LOGIN_URL="/THIS_IS_FINE/") def test_b(self): # settings appear to be overridden as expected self.assertEqual(settings.LOGIN_URL, "/THIS_IS_FINE/") response = self.client.get(reverse("redirect-to-login")) # The following assertion fails only when test_a() is run. self.assertRedirects(response, "/THIS_IS_FINE/", status_code=301, target_status_code=404 ) def test_c(self): response = self.client.get(reverse("harmless-view")) self.assertEqual(response.status_code, 301)
.F. ====================================================================== FAIL: test_b (override_bug.tests.OverrideSettingsTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "django/test/utils.py", line 224, in inner return test_func(*args, **kwargs) File "override_bug/override_bug/tests.py", line 24, in test_b target_status_code=404 File "django/test/testcases.py", line 617, in assertRedirects (url, expected_url)) AssertionError: Response redirected to 'http://testserver/THIS/SHOULD/BE/OVERRIDDEN/IN/THE/TEST/', expected 'http://testserver/THIS_IS_FINE/' ---------------------------------------------------------------------- Ran 3 tests in 0.031s
Attachments (1)
Change History (6)
by , 11 years ago
Attachment: | sample_project added |
---|
comment:1 by , 11 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I'm almost sure the problem is related to the way you are using settings.LOGIN_URL
. In your sample project, it is used as a parameter of the as_view
call in your URLConf, that means that it will be defined once and for all requests at import time.
You can workaround this issue by subclassing RedirectView
and overriding get_redirect_url()
so that when settings.LOGIN_URL
changes your view can take that change into account. I don't think we can do anything on Django's side.
comment:2 by , 11 years ago
Sorry for opening this ticket. You're right that this has nothing to do with Django.
I used django-braces' LoginRequiredMixin
which sets settings.LOGIN_URL
at import time and replicated this bug in my example project without further reflecting upon this issue.
comment:3 by , 11 years ago
I think I'm hitting the same issue as well. In my project, I have set a variable called REGISTRATION_ENABLED
. However, when I try to override this setting in my tests, it's never read. Changing the setting beforehand in my settings.py makes the test pass, however. This is how it's used in my tests:
def test_auth(self): """ Test that a user can register using the API, login and logout """ # test registration workflow submit = { 'username': 'Otto', 'password': 'password', 'first_name': 'first_name', 'last_name': 'last_name', 'email': 'email@email.com', 'is_superuser': False, 'is_staff': False, } url = '/api/auth/register' response = self.client.post(url, json.dumps(submit), content_type='application/json') self.assertEqual(response.status_code, 201) # test disabled registration with self.settings(REGISTRATION_ENABLED=False): submit['username'] = 'anothernewuser' response = self.client.post(url, json.dumps(submit), content_type='application/json') self.assertEqual(response.status_code, 403)
And the code block in my views:
class HasRegistrationAuth(permissions.BasePermission): """ Checks to see if registration is enabled """ def has_permission(self, request, view): return settings.REGISTRATION_ENABLED
Note that I'm using https://github.com/tomchristie/django-rest-framework in my application.
comment:4 by , 11 years ago
Resolution: | invalid |
---|---|
Status: | closed → new |
apologies, I forgot to add the output of my tests!
$ ./manage.py test api Creating test database for alias 'default'... .......F.................................................... ====================================================================== FAIL: test_auth (api.tests.test_auth.AuthTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/api/tests/test_auth.py", line 64, in test_auth self.assertEqual(response.status_code, 403) AssertionError: 201 != 403 ---------------------------------------------------------------------- Ran 60 tests in 29.056s FAILED (failures=1) Destroying test database for alias 'default'...
When i modify the setting to False
in settings.py, the test passes without failure.
comment:5 by , 11 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I think it's more likely that your use of override_settings()
is invalid. Please be sure you've read the caveats in the documentation and ask questions using our support channels. If after doing those setps you still believe you've found a bug, please open a new ticket, thanks.
An example project which exhibits the bug (filetype: tar)