I have started using Django's testing framework, and everything was working fine until I started testing authenticated pages.
For the sake of simplicity, let's say that this is a test:
class SimpleTest(TestCase):
def setUp(self):
user = User.objects.create_user('temporary', 'temporary@gmail.com', 'temporary')
def test_secure_page(self):
c = Client()
print c.login(username='temporary', password='temporary')
response = c.get('/users/secure/', follow=True)
user = User.objects.get(username='temporary')
self.assertEqual(response.context['email'], 'temporary@gmail.com')
After I run this test, it fails, and I see that printing return value of login() returns True, but response.content gets redirected to login page (if login fails authentication decorator redirects to login page). I have put a break point in decorator that does authentication:
def authenticate(user):
if user.is_authenticated():
return True
return False
and it really returns False. Line 4 in test_secure_page() properly retrieves user.
This is the view function:
@user_passes_test(authenticate, login_url='/users/login')
def secure(request):
user = request.user
return render_to_response('secure.html', {'email': user.email})
Of course, if I try to login through application (outside of test), everything works fine.
Token based authentication: I was in same situation. I found solution in which actually I did generate a user for login purpose in
setUp
method. Then later in the test methods, I tried to get the token and passed it along with request data.setUp:
test_method:
It can often be useful to use a custom auth backend that bypassess any sort of authentication during testing:
Then, during tests, add
yourapp.auth_backends.TestcaseUserBackend
to yourAUTHENTICATION_BACKENDS
:Then, during tests, you can simply call:
The problem is that you're not passing
RequestContext
to your template.Also, you probably should use the
login_required
decorator and the client built in theTestCase
class.I'd rewrite it like this: