Back to BlogQuality & Testing

Test My Django App: What an Outside QA Team Covers

Rupak Amin

Founder & Lead Engineer, RAITHub

7 min read

RAITHub ships and tests production software. See QA as a Service or talk to us.

Testing a Django app means covering four layers: models and business logic, views and forms, the API (usually Django REST Framework) with its permissions, and the few end-to-end journeys that matter. Use pytest with pytest-django against a disposable test database, the Django test client for views, and a browser tool for journeys. An outside QA team can do this whether or not they built the app.

If you would rather have the suite built and run for you, see how RAITHub would test this near the end. RAITHub builds in Python and tests apps in these stacks; testing a framework does not require having built in it.

What should a Django test suite cover?

Django's structure points the test plan. Models hold business rules and constraints; views and forms handle requests and validation; Django REST Framework (DRF) exposes the API with permission classes; migrations change the schema. Each needs its own kind of test, and the permission layer is where the expensive bugs hide.

LayerWhat to testTypical tool
Models and logicMethods, validators, constraints, signals; pure business rulespytest with pytest-django
Views and formsStatus, redirects, form validation, the right data for the right userDjango test client
API (DRF)Status, serializer output, authentication, permissions per role, errorsDRF APIClient / pytest
MigrationsThey apply cleanly, and data migrations transform rows correctlypytest against a fresh test DB
End-to-endSign-in, the core workflow, checkout, in a real browserPlaywright or Cypress

Most of the protection comes from the lower layers, which run fast against a test database. A small end-to-end set proves the whole thing holds together; that shape is the test pyramid, in the test pyramid for a SaaS.

What tools fit a Django app?

pytest with the pytest-django plugin is the common choice: it runs Django's tests with pytest's fixtures and clearer assertions, and manages the test database for you (pytest-django docs). Django's own test client and DRF's APIClient send requests to your views and endpoints in-process, so API tests run without a live server. For the browser journeys, Playwright or Cypress sits on top; Playwright vs Cypress in 2026 compares them, and the cross-browser testing checklist covers the browser pass.

Django creates and destroys a separate test database automatically, so tests never touch your real data (Django testing docs). Keep that behaviour: test against a real database, not mocks, so the tests catch wrong queries and unenforced constraints.

What does a good Django API test look like?

Test the endpoint through DRF's client with an authenticated user, and check both that the right user succeeds and that the wrong user is refused. The second half is the test that stops one user reading another's data. This pytest example uses the DRF APIClient:

Free checklist

AI-Built App Launch Readiness Checklist

25 checks before you let real users in. Enter your email and we’ll reveal it below (and send you a copy).

One email, the checklist, no spam. By submitting you agree we can email you this checklist and reply to your enquiry.

# tests/test_orders.py
import pytest
from rest_framework.test import APIClient

@pytest.mark.django_db
def test_user_cannot_read_another_users_order(alice, bob, make_order):
    order = make_order(owner=alice)

    client = APIClient()
    client.force_authenticate(user=bob)
    res = client.get(f"/api/orders/{order.id}/")

    assert res.status_code in (403, 404)

Write that kind of test for every endpoint and role. The django_db marker gives the test a clean database transaction that rolls back after it, so each test is independent. For the full endpoint checklist, status, schema, validation, authentication, idempotency and errors, see the API testing guide.

What breaks in a Django app in production?

The expensive Django bugs are usually data and permission bugs, not crashes. A migration that applies locally but fails on production data; a DRF permission class that protects the list view but not the detail view; a query that is correct but fires once per row and crawls under load; a form that accepts input the model constraint then rejects at the database. Tests at the model, view and API layers catch these before a deploy does.

FailureHow a test catches it
Migration fails on real dataRun migrations against a seeded test database in CI
Missing permission on a detail viewAuthorisation test per endpoint and role
N+1 query under loadAssert query counts, then load-test the endpoint
Constraint rejects valid-looking inputModel and form validation tests on edge cases

Buy, build or hire?

OptionChoose this whenWatch out for
A tool or SaaS testing platformYou want recorded browser checks fast, with little codeRecorded tests break often and live outside your repository
Freelancers or crowdtestingYou need a one-off manual pass before a launchNo suite remains, and no one maintains it
An in-house QA hireYou release weekly and want QA on the team long-termNeeds someone who writes Python, not only a manual tester
A managed QAaaS teamYou want the suite built across layers, gated in CI and kept currentMake sure the tests live in your repository and you own them

Why RAITHub for testing a Django app?

RAITHub tests apps in these stacks whether or not it built them, and Python is part of its own stack: PadhAI, the AI tutoring platform RAITHub built, runs 11 services, two of them in Python. The method does not change with the framework: map the risk, test the money and data paths at the lowest layer that catches them, and gate the suite in CI. The test counts come from real repositories, 400+ on this site, 750+ on TheSkinProof (the founder's own venture), 1,024 on PropDesk; how that discipline works is in QA-first development: how RAITHub tests.

When you don't need RAITHub: if you want an engineer placed inside your team under your management, that is staff augmentation, which RAITHub does not offer; and a prototype you reshape weekly may only need a short manual pass. For the broader method, see how to test a SaaS application.

How RAITHub would test this

Through QA and test automation, part of QA as a service, RAITHub would:

  • map your models, views, API endpoints and roles, and rank the money and data paths by cost of failure
  • write pytest tests for models and logic, Django test-client tests for views, and DRF tests with an authorisation matrix per role
  • test migrations against a seeded database, and add a small Playwright set for the journeys that matter
  • wire the suite into your CI so a failing change blocks the release, with tests and configuration in your repository

Buy it as a monthly QA plan, a fixed-price one-off audit, or a dedicated QA team that RAITHub manages and bills monthly. Testers are never placed under your management. You own the tests and the IP, and an NDA is signed first. Start with a free 15-minute call, then a written fixed quote. Talk to RAITHub about testing your Django app.

Frequently asked questions

How do I test a Django app?

Use pytest with pytest-django against a disposable test database: test models and logic, use the Django test client for views, test the DRF API with permissions per role, check migrations, and add a small browser suite for key journeys, all in CI.

Should I use pytest or Django's built-in test runner?

Both work. Many teams prefer pytest with pytest-django for its fixtures and clearer assertions, while it still manages Django's test database for you. The built-in runner is fine too; the layers you test matter more than the runner.

Do Django tests use my real database?

No. Django creates a separate test database and destroys it afterwards, so tests never touch real data. Keep testing against a real (test) database rather than mocks, so wrong queries and unenforced constraints are caught.

How do I test a Django REST Framework API?

Use DRF's APIClient to send authenticated requests and check status, serializer output and permissions. For every endpoint and role, add a test that a user cannot reach another user's data; that is the test that stops data leaks.

Can RAITHub test a Django app if it did not build it in Django?

Yes. Testing an app does not require having built it, and RAITHub works in Python. It starts with the money and data paths, writes tests that pin down current behaviour, and gates them in CI before widening coverage.

Will I own the tests?

Yes. The tests and CI configuration live in your repository, the IP is assigned to you, and the engagement runs month-to-month, so the suite keeps protecting you after it ends.

django testingpytestdjango rest frameworkapi testingpython testingQA as a service

Ready to discuss your project?

Book a free 15-minute technical audit with our engineering team.