Советы о том, как протестировать разрешения модели DRF с помощью TDD

#django #django-rest-framework #tdd #django-testing #django-permissions

#django #django-rest-framework #tdd #django-тестирование #django-разрешения

Вопрос:

Я пишу DRF API для образовательного веб-сайта, где пользователи могут получать доступ к данным на основе групп разрешений и разрешений уровня объекта, которые у них есть. Когда я начал писать тесты, я задался вопросом, нужно ли тестировать запросы со всеми возможными комбинациями разрешений. Например, скажем, одной конечной точке API требуется три разрешения для предоставления доступа к своим данным, тогда вы могли бы написать множество методов тестирования для проверки всех возможных комбинаций разрешений, которые могут быть у пользователя. Только одна комбинация, та, в которой у пользователя есть все три разрешения, приведет к данным, а остальные, скорее всего, приведут к ответу 403 «Запрещено».

В качестве примера, три разрешения могут быть чем-то вроде IsAuthenticated, isOwner и IsTeacher. Пользователь должен иметь все три разрешения, поэтому 403 запрещенных комбинации ответов будут:

 IsOwner    IsAuthenticated    IsTeacher
False      False              False,
False      False              True,
False      True               True,
True       False              False,
True       True               False,
True       False              True,
False      True               False,
  

Допустимый ответ, который предоставляет пользователю доступ к данным, будет:

 IsOwner    IsAuthenticated    IsTeacher
True       True               True
  

Обязательно ли тестировать их все? Должен ли я протестировать это другим способом?

Ответ №1:

Вам не нужно тестировать все комбинации, хотя лучше охватить все тестовые случаи, если вы чувствуете, что этого достаточно. Вы можете сделать это в одном тестовом примере, подобном этому. Вы можете изменить последовательность разрешений и написать новый регистр здесь, если хотите протестировать все комбинации.

 from rest_framework import status
from django.contrib.auth.models import Permission,User

class MyTest(APITestCase):
    client = APIClient()
    url = "/my/url/"

    def setUp(self):
            self.user = User.objects.create(username="hellouser")

    def test_user_permissions(self):
            res = self.client.post(self.url, data={"some": "data"}, format="json")
            self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
            #now give permission
            permission = Permission.objects.get(name='isOwner')
            self.user.user_permissions.add(permission) 
            res = self.client.post(self.url, data={"some": "data"}, format="json")
            self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
            #give another
            permission = Permission.objects.get(name='isTeacher')
            self.user.user_permissions.add(permission) 
            res = self.client.post(self.url, data={"some": "data"}, format="json")

            self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
            #last one should pass
            permission = Permission.objects.get(name='isAuthenticated')
            self.user.user_permissions.add(permission) 
            res = self.client.post(self.url, data={"some": "data"}, format="json")

            self.assertEqual(res.status_code, status.HTTP_200_OK)
  

Комментарии:

1. Спасибо, я понимаю, что вы можете избежать некоторых комбинаций. Я хотел знать, следует ли вам тестировать это так тщательно, что, как я теперь вижу, зависит от того, насколько тщательно я хочу это протестировать. Спасибо за вашу помощь и наглядный пример!

2. Где self.user вообще используется в этих запросах? Я не понимаю, как self.client узнает, кто этот пользователь.

3. @Mark def setUp(self): self.user = User.objects.create(username="hellouser") запускается первым при запуске теста, он назначен там.