Django Testing
Download
assert HTTPStatus.OK == response.status_code
content = io.BytesIO(b"".join(response.streaming_content))
assert "1-2-3" == content.read().decode("utf-8").strip()
assert (
'inline; filename="{}-1-2-3.txt"'.format(record.pk)
== response["Content-Disposition"]
)
CSV
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
Database
from django.db import IntegrityError
with pytest.raises(IntegrityError):
# ...
# not sure if the following is sensible (or not)?
assert "duplicate key value violates unique constraint" in str(e.value)
assert "pipeline_pipelinestep_pipeline_id_order" in str(e.value)
Errors
form = response.context["form"]
assert {
"comments": ["This field is required."],
"result": ["This field is required."],
} == form.errors
factory
If you have a factory which includes a FileField
:
import factory
class DocumentFactory(factory.django.DjangoModelFactory):
class Meta:
model = Document
document_file = factory.django.FileField(filename="my_document.doc")
You can supply a different file in the actual test as follows:
from django.core.files.uploadedfile import SimpleUploadedFile
document = DocumentFactory(
document_file=SimpleUploadedFile("your_document.doc", b"file contents"),
)
Or:
sample_pdf_file = pathlib.Path(
pathlib.Path.cwd(), "document", "tests", "data", "sample.pdf"
)
with open(sample_pdf_file, "rb") as f:
document_file = SimpleUploadedFile("my_blank_form.pdf", f.read())
document = DocumentFactory(document_file=document_file)
Tip
Don’t forget rb
in the open
if this is a binary file.
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.