Writing tests for the Django admin with pytest-django

I'm using pytest-django on a project and I wanted to write a test for a Django admin create form submission. Here's the pattern I came up with:

from .models import Location
import pytest


def test_admin_create_location_sets_public_id(client, admin_user):
    client.force_login(admin_user)
    assert Location.objects.count() == 0
    response = client.post(
        "/admin/core/location/add/",
        {
            "name": "hello",
            "state": "13",
            "location_type": "1",
            "latitude": "0",
            "longitude": "0",
            "_save": "Save",
        },
    )
    # 200 means the form is being re-displayed with errors
    assert response.status_code == 302
    location = Location.objects.order_by("-id")[0]
    assert location.name == "hello"
    assert location.public_id == "lc"

The trick here is to use the client and admin_user pytest-django fixtures (documented here) to get a configured test client and admin user object, then use client.force_login(admin_user) to obtain a session where that user is signed-in to the admin. Then write tests as normal.

Using the admin_client fixture

Even better: use the admin_client fixture provided by pytest-django which is already signed into the admin:

def test_admin_create_location_sets_public_id(admin_client):
    response = admin_client.post(
        "/admin/core/location/add/",
    # ...

Before finding out that this was included I implemented my own version of it:

import pytest


@pytest.fixture()
def admin_client(client, admin_user):
    client.force_login(admin_user)
    return client

# Then write tests like this:
def test_admin_create_location_sets_public_id(admin_client):
    response = admin_client.post(
        "/admin/core/location/add/",
    # ...

Created 2021-03-02T13:08:34-08:00, updated 2021-03-02T23:37:18-08:00 · History · Edit