pythondjangodjango-rest-frameworkdrf-yasg

How can I properly test swagger_auto_schema for methods, request_body, and responses in drf-yasg with pytest?


I’m working on testing a Django REST Framework (DRF) CartViewSet using pytest, and I need to verify the swagger_auto_schema properties like the HTTP method, request body, and responses for different actions (e.g., add, remove, clear).

I have the following code in my CartViewSet:

class CartViewSet(GenericViewSet, RetrieveModelMixin, ListModelMixin):
    # Other viewset code...

    @swagger_auto_schema(
        method="post",
        request_body=AddToCartSerializer,
        responses={
            201: openapi.Response(description="Item added successfully."),
            400: openapi.Response(description="Invalid input data"),
        },
    )
    @action(detail=False, methods=["post"], url_path="add")
    def add(self, request):
        # Logic for adding an item to the cart
        pass

Now, I want to write a pytest unit test to check the following for the add method:

  1. HTTP Method: Ensure the swagger_auto_schema method is POST.
  2. Request Body: Ensure the correct serializer (AddToCartSerializer) is set for the request body.
  3. Responses: Verify that the response status codes (201 and 400) and their descriptions are properly set.

Could someone guide me on how to properly test the swagger_auto_schema properties for method, request body, and responses in pytest?

Any help or insights would be greatly appreciated!


Solution

  • It's testable like this.

    def test_cart_viewset_add_swagger_documentation(self):
            """Test that the CartViewSet's add method has proper Swagger documentation."""
            # Get the add method from CartViewSet
            add_method = CartViewSet.add
    
            # Access the swagger schema from the method
            schema_info = getattr(add_method, "_swagger_auto_schema", {})
    
            # The structure has 'post' as the key since it's a POST method
            method_info = schema_info.get("post", {})
    
            # Verify request body is defined
            request_body = method_info.get("request_body", None)
            assert request_body == AddToCartSerializer
    
            # Verify responses are defined
            responses = method_info.get("responses", {})
            assert 201 in responses
            assert 400 in responses
    
            # Verify response content
            success_response = responses.get(201)
            assert isinstance(success_response, openapi.Response)
            assert success_response.description == "Item added successfully."
    
            error_response = responses.get(400)
            assert isinstance(error_response, openapi.Response)
            assert error_response.description == "Invalid input data"