Тестирование Django для входа в систему и сбора токенов
Пытаюсь написать тест для входа в Django. Я хочу запросить логин, собрать токен и получить доступ к различным функциям представления. Как мне написать тест в python для этого. За помощь благодарен.
Это зависит от вашего authentication system
, если вы используете Django default auth, вы можете просто использовать его вспомогательный метод login(**credentials)
или force_login
https://docs.djangoproject.com/en/4.1/topics/testing/tools/#django.test.Client.login
Если вы используете Django Rest Framework с дополнительной 3-й системой авторизации, вы можете использовать его класс тестирования
from rest_framework.test import APITestCase
class TestMyProtectedView(APITestCase):
def setUp(self) -> None:
self.client.login(user, password)
def test_view(self):
# now you can access your view with logged-in user in setUp
response = self.client.get('/api/views/')
Как описано в документациях Django и DRF. Это будет что-то вроде:
tests.py
from django.test import TestCase
from django.urls import reverse
from django.contrib.auth import get_user_model
from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient
from rest_framework import status
# Create your tests here.
class UserLoginTestCase(TestCase):
def setUp(self):
self.client = APIClient()
self.admin_user = get_user_model().objects.create_superuser(
email='admin@example.com',
password='testpass123',
)
def test_user_create_or_collect_token(self):
"""User check token created if in post save signal format"""
token = Token.objects.get(user__email=self.admin_user.email)
self.assertTrue(token.key)
def test_user_authenticated(self):
"""Check if user is authenticated"""
token = Token.objects.get(user__email=self.admin_user.email)
self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
r = self.client.get(reverse('user:me'))
self.assertEqual(r.status_code, status.HTTP_200_OK)
def test_user_login(self):
"""test user login"""
url = reverse('user:login')
data = {
'username': 'admin@example.com',
'password': 'testpass123'
}
r = self.client.post(url, data, format='json')
self.assertEqual(r.status_code, status.HTTP_200_OK)
self.assertTrue(r.data['token'])
urls.py
from .api.views import CustomAuthToken, UserAuthenticated
from django.urls import path
app_name = 'user'
urlpatterns = [
path('login/', CustomAuthToken.as_view(), name='login'),
path('me/', UserAuthenticated.as_view(), name='me'),
]
views.py
from rest_framework.views import APIView
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework import authentication, permissions
from core.models import User
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'token': token.key,
'user_name': user.name,
'email': user.email
})
class UserAuthenticated(APIView):
queryset = User.objects.all()
authentication_classes = [authentication.TokenAuthentication]
permission_classes = [permissions.IsAdminUser]
def get(self, request):
""" Check if user is authenticated by checking token against db """
is_authenticated = True
return Response({'isAuthenticated': is_authenticated})
Обычно тесты пишутся как для положительных, так и для отрицательных результатов.
Обратите внимание, что в данном случае, в частности, у меня есть пользовательская модель пользователя, а также расширен встроенный вид ObtainAuthToken.