Test & Document API0%
Test & Document API
Beginner12 min read•Updated: Jul 11, 2026
DRF Capstone: Automated Test Suite and Production Swagger Docs
To complete our capstone E-Commerce REST API, we implement comprehensive automated test coverage for the entire checkout flow and configure production-grade OpenAPI documentation.
1. Full E-Commerce Test Suite
Create store/tests/test_ecommerce_flow.py:
Python
from rest_framework.test import APITestCase
from rest_framework import status
from django.contrib.auth import get_user_model
from store.models import Category, Product, Cart, CartItem, Order
User = get_user_model()
class ECommerceAPITests(APITestCase):
def setUp(self):
self.user = User.objects.create_user(username='john_doe', password='secretpassword123')
self.category = Category.objects.create(name='Hardware', slug='hardware')
self.product = Product.objects.create(
category=self.category,
title='4K Ultra HD Monitor',
slug='4k-ultra-hd-monitor',
description='Crisp 3840x2160 IPS panel',
price=399.99,
inventory=10
)
def test_complete_e2e_shopping_flow(self):
# 1. Anonymous user creates a cart
cart_res = self.client.post('/api/v1/carts/', format='json')
self.assertEqual(cart_res.status_code, status.HTTP_201_CREATED)
cart_id = cart_res.data['id']
# 2. Add product to cart
add_item_url = f'/api/v1/carts/{cart_id}/items/'
item_res = self.client.post(
add_item_url,
{'product_id': self.product.id, 'quantity': 2},
format='json'
)
self.assertEqual(item_res.status_code, status.HTTP_201_CREATED)
# 3. Verify unauthenticated checkout fails
order_url = '/api/v1/orders/'
unauth_order_res = self.client.post(
order_url,
{'cart_id': cart_id, 'shipping_address': '100 Main St, Austin, TX'},
format='json'
)
self.assertEqual(unauth_order_res.status_code, status.HTTP_401_UNAUTHORIZED)
# 4. Authenticate user and checkout
self.client.force_authenticate(user=self.user)
order_res = self.client.post(
order_url,
{'cart_id': cart_id, 'shipping_address': '100 Main St, Austin, TX'},
format='json'
)
self.assertEqual(order_res.status_code, status.HTTP_201_CREATED)
# 5. Verify database state
self.product.refresh_from_db()
self.assertEqual(self.product.inventory, 8) # 10 - 2
self.assertFalse(Cart.objects.filter(id=cart_id).exists()) # Cart flushed
self.assertEqual(Order.objects.filter(customer=self.user).count(), 1)
2. Verifying Stock Depletion Fails Gracefully
Python
def test_checkout_fails_when_quantity_exceeds_stock(self):
# Create cart and add more than available inventory (15 > 10)
cart = Cart.objects.create()
CartItem.objects.create(cart=cart, product=self.product, quantity=15)
self.client.force_authenticate(user=self.user)
response = self.client.post(
'/api/v1/orders/',
{'cart_id': str(cart.id), 'shipping_address': '200 Oak Ave'},
format='json'
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.product.refresh_from_db()
self.assertEqual(self.product.inventory, 10) # Stock untouched
3. Production OpenAPI Documentation Verification
Run the spectacular schema check management command:
Bash / Terminal
python manage.py spectacular --validate --file schema.yml
This verifies that:
- 1Every serializer field has a valid OpenAPI primitive or component type.
- 2All custom filters and paginators are documented.
- 3There are zero schema generator warnings.
4. Summary of DRF Mastery
| Domain | Key Skills Mastered |
|---|---|
| Foundations | REST statelessness, HTTP status codes, serializers, serialization/deserialization |
| Views & Routing | APIView, Generic Views, ViewSets, DefaultRouter, ModelViewSet |
| Authentication | TokenAuth, SimpleJWT, Refresh Tokens, Custom Permissions, Object Permissions |
| Data Optimization | django-filter, SearchFilter, OrderingFilter, PageNumber/Cursor Pagination, select_related |
| Testing | APITestCase, APIClient, force_authenticate, factory_boy, E2E workflows |
| Documentation | drf-spectacular, OpenAPI 3.0, Swagger UI, Redoc, @extend_schema |
Interactive Quiz
Practice Quiz
Question 1
What does
python manage.py spectacular --validate do?Question 2
In an e-commerce API test, what does
self.product.refresh_from_db() guarantee after an order checkout?Question 3
Why should unauthenticated users be blocked from placing orders (
401 Unauthorized)?Question 4
What happens if a customer attempts to purchase more units than are in stock?
Question 5
What is the main benefit of providing both Swagger UI and Redoc documentation endpoints in production?
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| CRUD, Authentication, Filtering, Pagination | None |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.
PreviousPrevNext