
Django Tdd
Stand up pytest-django TDD for Django apps and DRF APIs with factories, mocks, and coverage from the first model or endpoint.
Overview
Django TDD is an agent skill most often used in Ship testing (also Build backend) that implements pytest-django TDD with factories, mocks, coverage, and DRF API tests.
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill django-tddWhat is this skill?
- Red–green–refactor TDD cycle with concrete Django user-creation example
- pytest-django configuration: reuse-db, nomigrations, coverage on apps, strict markers
- Separate test settings module pattern (config.settings.test)
- factory_boy and mocking guidance for models, views, and serializers
- Django REST Framework API testing strategies
- Red–green–refactor TDD cycle documented with step-by-step Django example
Adoption & trust: 5.3k installs on skills.sh; 210k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are building Django or DRF features without a pytest layout, factories, or a TDD habit, so regressions show up only after manual checks.
Who is it for?
Indie backends where you own models, views, serializers, and CI and want pytest-django as the default harness.
Skip if: Frontend-only stacks, Django projects committed to stdlib unittest only with no pytest migration appetite, or pure infrastructure/terraform work with no Python app code.
When should I use this skill?
Writing new Django applications, implementing Django REST Framework APIs, testing Django models views and serializers, or setting up testing infrastructure for Django projects.
What do I get? / Deliverables
You run a red–green–refactor loop with pytest.ini, test settings, factory_boy fixtures, and API tests so new Django behavior ships with automated coverage.
- pytest.ini and test settings layout
- Factory definitions and example test modules
- Coverage reports (HTML/term) for apps package
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Testing infrastructure and TDD rituals are cataloged under Ship testing even when you practice them during feature work. The skill centers on pytest.ini, test settings, factories, and API tests—the canonical QA shelf—not product ideation or deploy monitors.
Where it fits
Write a failing pytest for a new DRF list endpoint before adding the view and serializer.
Add pytest.ini, test settings, and coverage thresholds before merging a feature branch.
Capture a production bug with a regression test using factories and strict markers.
How it compares
Django-focused TDD workflow skill—not a generic Playwright E2E pack or a one-off linter rule.
Common Questions / FAQ
Who is django-tdd for?
Solo and indie builders shipping Django monoliths or DRF APIs who want pytest, factories, and TDD discipline without a dedicated QA engineer.
When should I use django-tdd?
In Ship testing while wiring pytest and coverage; in Build backend when implementing new models, views, or serializers test-first; and during Operate iterate when reproducing bugs with regression tests.
Is django-tdd safe to install?
It guides local test and config edits only; review the Security Audits panel on this Prism page and avoid granting unnecessary secrets access when agents run pytest.
SKILL.md
READMESKILL.md - Django Tdd
# Django Testing with TDD Test-driven development for Django applications using pytest, factory_boy, and Django REST Framework. ## When to Activate - Writing new Django applications - Implementing Django REST Framework APIs - Testing Django models, views, and serializers - Setting up testing infrastructure for Django projects ## TDD Workflow for Django ### Red-Green-Refactor Cycle ```python # Step 1: RED - Write failing test def test_user_creation(): user = User.objects.create_user(email='test@example.com', password='testpass123') assert user.email == 'test@example.com' assert user.check_password('testpass123') assert not user.is_staff # Step 2: GREEN - Make test pass # Create User model or factory # Step 3: REFACTOR - Improve while keeping tests green ``` ## Setup ### pytest Configuration ```ini # pytest.ini [pytest] DJANGO_SETTINGS_MODULE = config.settings.test testpaths = tests python_files = test_*.py python_classes = Test* python_functions = test_* addopts = --reuse-db --nomigrations --cov=apps --cov-report=html --cov-report=term-missing --strict-markers markers = slow: marks tests as slow integration: marks tests as integration tests ``` ### Test Settings ```python # config/settings/test.py from .base import * DEBUG = True DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:', } } # Disable migrations for speed class DisableMigrations: def __contains__(self, item): return True def __getitem__(self, item): return None MIGRATION_MODULES = DisableMigrations() # Faster password hashing PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.MD5PasswordHasher', ] # Email backend EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # Celery always eager CELERY_TASK_ALWAYS_EAGER = True CELERY_TASK_EAGER_PROPAGATES = True ``` ### conftest.py ```python # tests/conftest.py import pytest from django.utils import timezone from django.contrib.auth import get_user_model User = get_user_model() @pytest.fixture(autouse=True) def timezone_settings(settings): """Ensure consistent timezone.""" settings.TIME_ZONE = 'UTC' @pytest.fixture def user(db): """Create a test user.""" return User.objects.create_user( email='test@example.com', password='testpass123', username='testuser' ) @pytest.fixture def admin_user(db): """Create an admin user.""" return User.objects.create_superuser( email='admin@example.com', password='adminpass123', username='admin' ) @pytest.fixture def authenticated_client(client, user): """Return authenticated client.""" client.force_login(user) return client @pytest.fixture def api_client(): """Return DRF API client.""" from rest_framework.test import APIClient return APIClient() @pytest.fixture def authenticated_api_client(api_client, user): """Return authenticated API client.""" api_client.force_authenticate(user=user) return api_client ``` ## Factory Boy ### Factory Setup ```python # tests/factories.py import factory from factory import fuzzy from datetime import datetime, timedelta from django.contrib.auth import get_user_model from apps.products.models import Product, Category User = get_user_model() class UserFactory(factory.django.DjangoModelFactory): """Factory for User model.""" class Meta: model = User email = factory.Sequence(lambda n: f"user{n}@example.com") username = factory.Sequence(lambda n: f"user{n}") password = factory.PostGenerationMethodCall('set_password', 'testpass123') first_name = factory.Faker('first_name') last_name = factory.Faker('last_name') is_active = True class CategoryFactory(factor