A Django app to generate basic tests for Django Rest Framework
Project description
drf-test-generator
This is a Django Package that generates basic tests for Django REST Framework.
Features
- Generates tests for all
ViewSets
in a Django REST Frameworkrouter
- Generates tests for all custom
actions
in aViewSet
- Generates tests for all
HTTP
methods in aViewSet
- Supports test generation for both
pytest
andunittest
Installation
pip install drf-test-generator
Setup
Add drf_test_generator
to your INSTALLED_APPS
in settings.py
:
INSTALLED_APPS = [
# ...
"drf_test_generator",
]
Note: This is required for the Django Management Command. You can remove it from INSTALLED_APPS
once you have generated the tests.
Generate Tests
Django Management Command
You can generate tests using the Django Management Command:
python manage.py generate_viewset_tests -r api.urls.router
Note: Currently this package only supports test generation for ViewSets that are registered in a router.
Django Management Command Options
-r
or --router
(REQUIRED)
The dotted path to the REST framework url router. This is the router that contains the ViewSets you want to generate tests for.
Example: --router api.urls.router
--test-base-class
The dotted path to the test base class. This is the class that your tests will inherit from. If not provided, the tests will inherit from rest_framework.test.APITestCase
.
Example: --test-base-class tests.base.MyCustomTest
--namespace
The namespace to use for the URLs (e.g: api_v1:posts-list
). If not provided, no namespace will be used.
Example: --namespace api_v1
--output-file
The path to the output file. If not provided, the tests will be printed to the console.
Example: --output-file tests.py
--select-viewsets
A list of ViewSets to generate tests for. If not provided, tests will be generated for all ViewSets in the router.
Example: --select-viewsets PostViewSet CommentViewSet
--variant
The test variant to generate. Options: pytest
, unittest
. If not provided, unittest
will be used.
Example: --variant pytest
--pytest-markers
A list of pytest markers to add to the generated tests. If not provided, only the @pytest.mark.django_db
marker will be added.
Example: --pytest-markers pytest.mark.ignore_template_errors pytest.mark.urls('myapp.test_urls')
--pytest-fixtures
A list of pytest fixtures to add to the generated tests. If not provided, only the client
fixture will be added.
Example: --pytest-fixtures django_user_model
Examples Usage
For the following code
# api/views.py
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
class PostViewSet(viewsets.ModelViewSet):
# ...
@action(detail=False, methods=["get", "post"], url_path="custom-action")
def custom_action(self, request):
return Response()
@action(detail=True, methods=["get", "options", "put"], url_path="new-action")
def custom_action2(self, request):
return Response()
# api/urls.py
from rest_framework import routers
router = routers.DefaultRouter()
router.register("posts", PostViewSet, basename="post")
For Unittest
Run Command
python manage.py generate_viewset_tests -r api.urls.router
Output
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
class PostViewSetTests(APITestCase):
def test_post_list_get(self):
url = reverse("post-list")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_create_post(self):
url = reverse("post-list")
response = self.client.post(url, data={})
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_post_custom_action_get(self):
url = reverse("post-custom-action")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_custom_action_post(self):
url = reverse("post-custom-action")
response = self.client.post(url, data={})
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_post_retrieve_get(self):
url = reverse("post-detail", kwargs={"pk": None})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_update_put(self):
url = reverse("post-detail", kwargs={"pk": None})
response = self.client.put(url, data={})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_partial_update_patch(self):
url = reverse("post-detail", kwargs={"pk": None})
response = self.client.patch(url, data={})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_destroy_delete(self):
url = reverse("post-detail", kwargs={"pk": None})
response = self.client.delete(url)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
def test_post_custom_action2_get(self):
url = reverse("post-custom-action2", kwargs={"pk": None})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_custom_action2_options(self):
url = reverse("post-custom-action2", kwargs={"pk": None})
response = self.client.options(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_post_custom_action2_put(self):
url = reverse("post-custom-action2", kwargs={"pk": None})
response = self.client.put(url, data={})
self.assertEqual(response.status_code, status.HTTP_200_OK)
For Pytest
Run Command
python manage.py generate_viewset_tests -r api.urls.router --variant pytest
Output
from django.urls import reverse
from rest_framework import status
import pytest
# PostViewSet Tests
@pytest.mark.django_db
def test_post_list_get(client):
url = reverse("post-list")
response = client.get(url)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_create_post(client):
url = reverse("post-list")
response = client.post(url, data={})
assert response.status_code == status.HTTP_201_CREATED
@pytest.mark.django_db
def test_post_custom_action_get(client):
url = reverse("post-custom-action")
response = client.get(url)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_custom_action_post(client):
url = reverse("post-custom-action")
response = client.post(url, data={})
assert response.status_code == status.HTTP_201_CREATED
@pytest.mark.django_db
def test_post_retrieve_get(client):
url = reverse("post-detail", kwargs={"pk": None})
response = client.get(url)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_update_put(client):
url = reverse("post-detail", kwargs={"pk": None})
response = client.put(url, data={})
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_partial_update_patch(client):
url = reverse("post-detail", kwargs={"pk": None})
response = client.patch(url, data={})
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_destroy_delete(client):
url = reverse("post-detail", kwargs={"pk": None})
response = client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
@pytest.mark.django_db
def test_post_custom_action2_get(client):
url = reverse("post-custom-action2", kwargs={"pk": None})
response = client.get(url)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_custom_action2_options(client):
url = reverse("post-custom-action2", kwargs={"pk": None})
response = client.options(url)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_post_custom_action2_put(client):
url = reverse("post-custom-action2", kwargs={"pk": None})
response = client.put(url, data={})
assert response.status_code == status.HTTP_200_OK
License
The code in this project is released under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for drf_test_generator-0.0.5-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 951d118356382f0c9647c2fdd5b7f556c51fbfc9a8e441e74c4a32da7811a779 |
|
MD5 | 39ad15de23d3b7adbfa9cbb12a70ed6b |
|
BLAKE2b-256 | 23336d2bf366e1e329e9972bd0f16f4da395913cf19e644c35d9d9dab52fb755 |