Package: drf-api-action
The drf-api-action Python package is designed to elevate your testing experience for Django Rest Framework (DRF) REST endpoints.
With the custom decorator api-action, this package empowers you to effortlessly test your REST endpoints as if they were conventional functions.Features:Simplified Testing:Testing DRF REST endpoints using the api-action decorator, treating them like regular functions.Seamless Integration:Replacing DRF's action decorator with api-action in your WebViewSet seamlessly.Clear Traceback:Instead of getting a response with error code, get the real traceback that led to the error.Pagination Support: Paginating easily through pages by a single kwarg.This package was designed in a way that you can use it in the following ways:As a pytest fixtureAs part of your ViewSet implementationDemoInstallationYou can installdrf-api-actionusing pip:pipinstalldrf-api-actionUsageTo usedrf-api-actionas a Pytest fixture, you need to follow these steps:Step 1: Import the Required Classes and our fixtureimportpytestfromtests.test_app.modelsimportDummyModelfromtests.test_app.viewsimportDummyViewSetFixturefromdrf_api_action.fixturesimportaction_apiStep 2: use the following action_api mark decorator:@pytest.mark.action_api(view_set_class={YOUR VIEW_SET})e.g:
our ViewSet is calledDummyViewSetFixture@pytest.mark.action_api(view_set_class=DummyViewSetFixture)deftest_call_as_api_fixture(db,action_api):passNow you can use allDummyViewSetFixturefunctionality!Step 3: write your teste.g:
our ViewSet is calledDummyViewSetFixture@pytest.mark.action_api(view_set_class=DummyViewSetFixture)deftest_call_as_api_fixture(db,action_api):dummy_model=DummyModel()dummy_model.dummy_int=1dummy_model.save()res=action_api.api_dummy(pk=1)assertres["dummy_int"]==1To usedrf-api-actionin your ViewSet, you need to follow these steps:Step 1: Import the Required Classes and DecoratorsImport the necessary classes and decorators fromdrf-api-actionandrest_framework:fromdrf_api_action.decoratorsimportaction_apifromdrf_api_action.mixinsimportAPIRestMixinfromrest_framework.viewsetsimportModelViewSetStep 2: InheritAPIRestMixinin your ViewCreate your view class by inheriting theAPIRestMixinclass.For example, we want to inheritModelViewSet(Could be any ViewSet) in our View:classDummyView(APIRestMixin,ModelViewSet):queryset=DummyModel.objects.all()serializer_class=DummySerializerAnother example:classUsersViewSet(APIRestMixin,mixins.RetrieveModelMixin,mixins.ListModelMixin,viewsets.GenericViewSet):serializer_class=UsersSerializerStep 3: Define Your API ActionsUse theaction_apidecorator instead ofactiondecorator to define your API actions as functions inside your view class:From:@action(detail=True,methods=["get"],serializer_class=DummySerializer)defdummy(self,request,**kwargs):serializer=self.get_serializer(instance=self.get_object())returnResponse(data=serializer.data,status=status.HTTP_200_OK)To:@action_api(detail=True,methods=["get"],serializer_class=DummySerializer)defdummy(self,request,**kwargs):serializer=self.get_serializer(instance=self.get_object())returnResponse(data=serializer.data,status=status.HTTP_200_OK)In the example above, thedummyfunction is decorated withaction_api.
It specifies that the action requires a detail argument, supports theGETmethod, and uses theDummySerializerfor serialization.Step 4: test REST methodsCreate an instance of your view class and call the API actions as regular functions:deftest_dummy():api=DummyView()result=api.dummy(pk=1)assertresult['dummy_int']==1query parameters/post payload are treated as function arguments as kwargsExceptions are raised explicitly:deftest_dummy():api=DummyView()result=api.dummy(pk='bbb')assertresult['dummy_int']==1tests/functionality_tests/test_as_api.py:11(test_call_as_api)self=<django.db.models.fields.BigAutoField:id>,value='bb'defget_prep_value(self,value):value=super().get_prep_value(value)ifvalueisNone:returnNonetry:
>returnint(value)EValueError:invalidliteralforint()withbase10:'bb'../venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py:2053:ValueError

Theaboveexceptionwasthedirectcauseofthefollowingexception:queryset=<QuerySet[<DummyModel:DummyModelobject(1)>]>,filter_args=()filter_kwargs={'pk':'bb'}defget_object_or_404(queryset,*filter_args,**filter_kwargs):"""Same as Django's standard shortcut, but make sure to also raise 404if the filter_kwargs don't match the required types."""try:
>return_get_object_or_404(queryset,*filter_args,**filter_kwargs)../venv/lib/python3.9/site-packages/rest_framework/generics.py:19:andsoon....Pagination support withpage/offsetkwarg (depends onDEFAULT_PAGINATION_CLASS):>>>api=DummyAPIViewSet()>>>response=api.by_dummy_int(request=None,dummy_int=1,page=2)>>>{'count':2,'next':None,'previous':'','results':[OrderedDict([('id',2),('dummy_int',1)])]}Package TestingThedrf-api-actionlibrary includes tests to ensure the functionality works as expected. To run the tests, follow these steps:Navigate to the root directory of thedrf-api-action/project.cdtests/Run the tests usingpytestpython-mpytest-vvThe tests will be executed, and the results will be displayed in the console.ExampleExample of using drf-api-action in aDRF projectSupport & ContributionFor guidance on support & contribution, see thecontributing guidelines.Bug ReportFor guidance on how to open a bug, see thebug report template.Open an IssueFor guidance on how to open an issue, see theissue template.Code Of Conductcode of conduct.