Ich habe angefangen, Djangos Test-Framework zu verwenden, und alles funktionierte gut, bis ich mit dem Testen authentifizierter Seiten begann.
Nehmen wir zur Vereinfachung an, dass dies ein Test ist:
class SimpleTest(TestCase):
def setUp(self):
user = User.objects.create_user('temporary', '[email protected]', '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'], '[email protected]')
Nachdem ich diesen Test ausgeführt habe, schlägt der Test fehl und ich sehe, dass beim Drucken des Rückgabewerts von login () True zurückgegeben wird, aber response.content zur Anmeldeseite umgeleitet wird (wenn bei der Anmeldung der Authentifizierungs-Dekorator fehlschlägt leitet zur Anmeldeseite um). Ich habe in Decorator einen Haltepunkt gesetzt, der die Authentifizierung durchführt:
def authenticate(user):
if user.is_authenticated():
return True
return False
und es gibt wirklich False zurück. Zeile 4 in test_secure_page () ruft den Benutzer ordnungsgemäß ab.
Dies ist die Ansichtsfunktion:
@user_passes_test(authenticate, login_url='/users/login')
def secure(request):
user = request.user
return render_to_response('secure.html', {'email': user.email})
Wenn ich versuche, mich über die Anwendung anzumelden (außerhalb des Tests), funktioniert alles einwandfrei.
Das Problem ist, dass Sie RequestContext
nicht an Ihre Vorlage übergeben.
Außerdem sollten Sie wahrscheinlich den login_required
-Dekorator und den in der TestCase
-Klasse erstellten Client verwenden.
Ich würde es so umschreiben:
#views.py
from Django.contrib.auth.decorators import login_required
from Django.shortcuts import render
from Django.contrib.auth import get_user_model
@login_required(login_url='/users/login')
def secure(request):
user = request.user
return render(request, 'secure.html', {'email': user.email})
#tests.py
class SimpleTest(TestCase):
def setUp(self):
User = get_user_model()
user = User.objects.create_user('temporary', '[email protected]', 'temporary')
def test_secure_page(self):
User = get_user_model()
self.client.login(username='temporary', password='temporary')
response = self.client.get('/manufacturers/', follow=True)
user = User.objects.get(username='temporary')
self.assertEqual(response.context['email'], '[email protected]')
Es kann oft nützlich sein, ein benutzerdefiniertes auth-Backend zu verwenden, das während des Tests jegliche Art von Authentifizierung umgeht:
from Django.contrib.auth import get_user_model
class TestcaseUserBackend(object):
def authenticate(self, testcase_user=None):
return testcase_user
def get_user(self, user_id):
User = get_user_model()
return User.objects.get(pk=user_id)
Fügen Sie während des Tests yourapp.auth_backends.TestcaseUserBackend
zu Ihrem AUTHENTICATION_BACKENDS
hinzu:
AUTHENTICATION_BACKENDS = [
"akindi.testing.auth_backends.TestcaseUserBackend",
]
Dann können Sie während der Tests einfach anrufen:
from Django.contrib.auth import login
user = User.objects.get(…)
login(testcase_user=user)
Token-basierte Authentifizierung: Ich befand mich in derselben Situation. Ich fand Sloution, in dem ich Benutzer für den Anmeldungszweck in SetUp-Methode erstellt habe. Später in den Testmethoden habe ich versucht, das Token zu erhalten und es mitzugeben Daten anfordern.
Konfiguration:
1> Benutzer anlegen Ex.
self.pravesh = User.objects.create(email='[email protected]',first_name='Pravesh',last_name='aaabbb',phone='5456165156',phonecountrycode='91')
2> Passwort für den Benutzer einstellen
Testmethode:
1> Client erstellen
Ex.client.login(email=self.pravesh.email, password=self.password)
2> get token (bei token auth) Ex
token = Token.objects.create(user=self.pravesh)
2> Login-Informationen weitergeben Z
`response = client.post(
reverse('account:post-data'),
data = json.dumps(self.data),
HTTP_AUTHORIZATION='Token {}'.format(token),
content_type = 'application/json'
)`