Django Testing

CSV Download

Tip

The view under test is Django View.

import io

@pytest.mark.django_db
def test_report_consent_user():
    with io.StringIO() as response:
        result = _report(response)
        response.seek(0)
        result = response.readlines()
    header = "name,email,consent\r\n"
    assert [
        header,
        "A Kimber,a@test.com,Y\r\n",
        "B Orange,b@b.com,\r\n",
    ] == result

Errors

form = response.context["form"]
assert {
    "comments": ["This field is required."],
    "result": ["This field is required."],
} == form.errors

Initial

Use form.initial:

assert HTTPStatus.OK == response.status_code
assert "form" in response.context
form = response.context["form"]
assert user == form.initial["name"]

If there are no initial values set on a form:

assert {} == form.initial

Messages

assert "messages" in response.context
messages = response.context["messages"]
assert 1 == len(messages)
assert ["Cannot create invoice - no hourly rate"] == [
    str(x) for x in messages
]

Queryset

form = response.context["form"]
name = form.fields["name"]
assert ["a", "c"] == [x.username for x in name.queryset]

RequestFactory

It might be easier to test views using a request factory. pytest-django includes rf, a request factory fixture:

def test_title(rf):
    url = reverse("mailing.list")
    request = rf.post(url, data={"category_id": category_id})
    request.user = UserFactory(is_staff=True)
    response = MailingListReportFormView.as_view()(request)
    assert HTTPStatus.FOUND == response.status_code

Note

If the view needs an authenticated user, we set the user on the request.