Можно ли подпараметризировать значения параметров pytest?

Я работаю над проектом DRF (REST API) и использую pytest. Довольно часто я обнаруживаю, что пишу почти идентичные тестовые параметры, и мне стало интересно, есть ли что-то, что я упускаю. Я не читал всю документацию по pytest, хотя я определенно прочитал всю главу документации django по тестам (не очень полезную в моем случае), и теперь я потратил несколько часов, пытаясь найти решение. Предположим, что у меня есть представление вроде этого:

from rest_framework import generics
from myapp.permissions import IsStaff, IsAdmin

class MessagesListView(generics.ListAPIView):
    permission_classes = [IsStaff | IsAdmin] 
    # ...

(Примечание: для примера предположим, что пользователь с правами IsAdmin не обязательно имеет права IsStaff; суть вопроса не в этом)

Для этого представления я написал тест:

import pytest
from rest_framework.reverse import reverse_lazy
from pytest_lazy_fixture import lazy_fixture

class TestMessagesListViewPermissions:
    def get_response(self, client):
        url = reverse_lazy("api:messages-list")
        return client.get(url)
    
    @pytest.mark.parametrize(
        argnames=["client", "expected_response_status"],
        argvalues=[
            pytest.param(
                "anonymous_client",
                status.HTTP_403_FORBIDDEN,
            ),
            pytest.param(
                "authenticated_client",
                status.HTTP_403_FORBIDDEN,
            ),
            pytest.param(
                "staff_client",
                status.HTTP_200_OK,
            ),
            pytest.param(
                "admin_client",
                status.HTTP_200_OK,
            ),
        ],
    )
    def test__permissions(self, client, expected_response_status):
        # WHEN
        response = self.get_response(client)
        # THEN
        assert response.status_code == expected_response_status

Есть 4 различных значения client, но 1+2-й и 3+4-й приводят к одному и тому же коду статуса ответа. Как я уже сказал, это упрощенный пример, но что если параметров будет 10? Я бы хотел иметь возможность сделать что-то вроде этого:

@pytest.mark.parametrize(
    argnames=["client", "expected_response_status"],
    argvalues=[
        pytest.param(
            ParamList["anonymous_client", "authenticated_client"],
            status.HTTP_403_FORBIDDEN,
        ),
        pytest.param(
            ParamList["staff_client", "admin_client"],
            status.HTTP_200_OK,
        ),
    ],
)

Есть ли какая-нибудь функция pytest, которую я упускаю, или плагин, который делает это возможным?

Вы рассматривали pytest-subtests?

Здесь долго обсуждаются его преимущества и недостатки: https://blog.ganssle.io/articles/2020/04/subtests-in-python.html

Вернуться на верх