Automated API Tests0%

Automated API Tests

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Automated API Integration Tests and Model Factories

As test suites grow from tens to hundreds of test cases, manual Model.objects.create(...) calls result in fragile, verbose, and difficult-to-maintain test setups. Using factory_boy and faker provides clean, dynamic mock fixtures, while end-to-end integration tests verify complete business workflows.


1. Setting Up factory_boy for DRF Models

factory_boy generates realistic model instances with foreign keys, default attributes, and sequence counters.

Bash / Terminal
pip install factory_boy faker

Create store/factories.py:

Python
import factory
from django.contrib.auth import get_user_model
from store.models import Category, Product, Order, OrderItem
 
User = get_user_model()
 
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = User
 
username = factory.Faker('user_name')
email = factory.Faker('email')
first_name = factory.Faker('first_name')
last_name = factory.Faker('last_name')
 
class CategoryFactory(factory.django.DjangoModelFactory):
class Meta:
model = Category
 
name = factory.Sequence(lambda n: f'Category {n}')
slug = factory.Sequence(lambda n: f'category-{n}')
 
class ProductFactory(factory.django.DjangoModelFactory):
class Meta:
model = Product
 
category = factory.SubFactory(CategoryFactory)
title = factory.Faker('catch_phrase')
sku = factory.Sequence(lambda n: f'SKU-{n:05d}')
price = factory.Faker('pydecimal', left_digits=3, right_digits=2, positive=True)
inventory = 50

2. Using Factories in API Integration Tests

Notice how concise and expressive test setup becomes:

Python
from rest_framework.test import APITestCase
from rest_framework import status
from store.factories import UserFactory, ProductFactory, CategoryFactory
 
class ProductSearchIntegrationTests(APITestCase):
def setUp(self):
self.user = UserFactory()
self.cat_laptops = CategoryFactory(name='Laptops')
self.cat_audio = CategoryFactory(name='Audio')
# Batch create products
self.macbook = ProductFactory(category=self.cat_laptops, title='Apple MacBook Pro 16')
self.dell = ProductFactory(category=self.cat_laptops, title='Dell XPS 15')
self.headphones = ProductFactory(category=self.cat_audio, title='Sony WH-1000XM5 Headphones')
 
def test_filter_by_category_returns_matching_products(self):
response = self.client.get('/api/v1/products/', {'category': self.cat_laptops.id})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 2)
titles = [p['title'] for p in response.data['results']]
self.assertIn('Apple MacBook Pro 16', titles)
self.assertIn('Dell XPS 15', titles)
self.assertNotIn('Sony WH-1000XM5 Headphones', titles)

3. End-to-End Workflow Testing: Order Checkout

Integration tests should test multi-step workflows representing real client interactions:

Python
class CheckoutWorkflowTests(APITestCase):
def setUp(self):
self.customer = UserFactory()
self.product = ProductFactory(price=100.00, inventory=10)
 
def test_complete_checkout_workflow(self):
self.client.force_authenticate(user=self.customer)
# Step 1: Create 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']
 
# Step 2: Add item to cart
item_res = self.client.post(
f'/api/v1/carts/{cart_id}/items/',
{'product': self.product.id, 'quantity': 2},
format='json'
)
self.assertEqual(item_res.status_code, status.HTTP_201_CREATED)
 
# Step 3: Checkout order
checkout_res = self.client.post(
'/api/v1/orders/',
{'cart_id': cart_id, 'shipping_address': '123 Tech Lane, San Francisco, CA'},
format='json'
)
self.assertEqual(checkout_res.status_code, status.HTTP_201_CREATED)
self.assertEqual(checkout_res.data['total_price'], '200.00')
 
# Step 4: Verify stock deduction
self.product.refresh_from_db()
self.assertEqual(self.product.inventory, 8)

Interactive Quiz

Practice Quiz

Question 1
What primary benefit does factory_boy provide in Django test suites?
Question 2
What is factory.SubFactory() used for in factory_boy?
Question 3
How does factory.Sequence() prevent database uniqueness constraint collisions?
Question 4
What distinguishes an integration test from an isolated unit test in DRF?
Question 5
In an end-to-end order placement test, why must product.refresh_from_db() be called?
Next Lesson

Swagger UI Integration

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext