A Django app to generate basic tests for Django Rest Framework
Project description
drf-test-generator
A Django Package that generates basic tests for Django REST Framework.
It can generate both unittest
and pytest
Style tests for all ViewSets
in a Django REST Framework router
.
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
Requirements
- Python 3.8+
- Django 4.2+
- Django REST Framework 3.12+
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
File details
Details for the file drf_test_generator-0.0.6.tar.gz
.
File metadata
- Download URL: drf_test_generator-0.0.6.tar.gz
- Upload date:
- Size: 12.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e487d23d98de22559d2c69d4bd915b373b0d5252fa36aedf4dd09e1fa458b6b8 |
|
MD5 | 4c0246f8ac515bfee2864798ebc354dd |
|
BLAKE2b-256 | 32cd3a6caca1f845ab1c76963c5f87aef9df09dca769bae173674240ec9e2fa0 |
File details
Details for the file drf_test_generator-0.0.6-py3-none-any.whl
.
File metadata
- Download URL: drf_test_generator-0.0.6-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ed1ca1bbb7fd00613889802dcf55ba5c4a11b5cd8fa2f1f91af1979c8023fe0f |
|
MD5 | c1d6d2316b8c076001351669f06061f5 |
|
BLAKE2b-256 | 29d82ec621fe4fcd3c81e6d208e684d54beaf25f40b56c6958b8bffa73f825e3 |