Django Test Data
Most slow Django suites spend time building data they do not need or exercising full request/database paths for behavior that can be tested at a smaller boundary. Use this skill to reduce setup cost while keeping representative integration coverage.
Refactoring Workflow
Map the behavior under test.
- Identify the smallest useful boundary: function, form, model method, middleware, command helper, view, or full request path.
- Keep a few integration tests for wiring; move detailed cases to unit tests where the boundary is clean.
Choose the fastest test base class.
SimpleTestCase: no database access.TestCase: ordinary database tests with rollback.TransactionTestCase: committed transaction behavior only.LiveServerTestCase: browser/live-server tests only.
Remove broad fixture data.
- Avoid large fixture files and base classes that always create objects.
- Build only the data each test or class needs.
Use factories deliberately.
- Start with small factory functions when the domain is simple.
- Use Factory Boy or Model Bakery when relationships and variants become repetitive.
Share class-level data with
setUpTestData.- Use
setUpTestData()for database objects reused by multiple methods in aTestCase. - Avoid mutating shared in-memory objects across methods.
- Use
Optimize database access in test setup and assertions.
- Use
select_related,prefetch_related, orbulk_createwhere setup/query cost is the bottleneck. - Assert query counts for hot paths when performance is part of the contract.
- Use
Read patterns.md for examples and decision details.
Decision Rules
- If a test does not need the database, use
SimpleTestCase. - If only some tests need the database, split them into separate classes.
- If a test requires committed transaction behavior, first check whether
captureOnCommitCallbacks()or an inneratomic()is enough. - If many tests share expensive objects, use
setUpTestDatainstead ofsetUp. - If fixture files are hard to understand or grow over time, replace them with factories.
- If a test depends on hard-coded auto-increment IDs, fix the assertion rather than enabling
reset_sequences=True. - Combine assertions when they describe one behavior produced by one expensive action.
Common Mistakes
- Testing form validation only through rendered HTML instead of inspecting form errors directly.
- Leaving management-command business logic inside
handle(), forcing tests throughcall_command(). - Using
TransactionTestCaseas the default. - Putting data in a base
TestCasethat only a few subclasses need. - Treating factories as permission to create a large object graph for every test.
- Mutating objects created by
setUpTestDataand leaking in-memory state to later tests.
Verification
Before finishing a refactor:
- The old behavior remains covered at the right level.
- Database-using and non-database tests are split where useful.
- Repeated setup moved to
setUpTestDataor factories only where it reduces cost. - Relevant tests pass individually and as part of their module/class.
Source: hashgraph-online/awesome-codex-plugins → plugins/LVTD-LLC/skills/skills/django-test-data/SKILL.md