Testing views.py
Send requests to views, analyze the response and any side effects. View tests are single source of truth for the backend and a blueprint for ui to follow on how to interact with backend
Workflow: Writing a test for a FBV
Create
./apps/my_app/tests/test_views.py, loadpytest-djangoplugin:import pytest pytestmark = [pytest.mark.django_db]
Define descriptive name, load
clientfixture:def test_book_author_create_form_success(client):
Define url name, make sure it is registered in
urls.py:from django.urls import reverse url = reverse('books:get_authors')
Define payload for the view
Assert the response and side effects:
assert r.status_code == 200 assert Author.objects.filter(name=payload['new_author_name']).exists()
Workflow: Writing a test for a CBV:
Name it
class TestThoughtViewDefine data fixture whole class will use:
@pytest.fixture def thoughts(self): return f.ThoughtFactory.create_batch(22)
Define test method name:
test_(http method)_(action name)_(desired outcome)Other steps are similar to FBVWithin method, start with url:
url = reverse('intray:thought')
Define
action:action = 'get-new-page'
Define
payload:payload = reverse('intray:thought')
Properties: Payload types
File:
from django.core.files.uploadedfile import SimpleUploadedFile file = SimpleUploadedFile( name="notes.txt", content=b'Dummy content of file', content_type="text/plain" ) payload = { 'file': file } r = client.post(url, data=payload)
views.py
file = request.FILES.get('file')
GET:
payload = { 'page': '1' } r = client.get(url, data=payload)
views.py
page = request.GET.get('page')
POST:
payload = { 'new_author_name': 'Jim' } r = client.post(url, data=payload)
views.py
name = request.POST.get('new_author_name')
See how url changes to hit specific author
PUT:
url = reverse('books:author_detail', args=[author.pk]) payload = 'name=Updated+Name' r = client.post(url, data=payload, content_type='application/x-www-form-urlencoded')
views.py
from django.http import QueryDict put_data = QueryDict(request.body) name = put_data.get('name')
DELETE:
url = reverse('books:author_detail', args=[author.pk]) r = client.delete(url)
views.py
author = Author.objects.get(pk=pk).delete()
Properties: Assertion types
Status code:
assert r.status_code == 200
Returned template context:
payload = { 'new_author_name': 'Jim' } r = client.post(url, data=payload) assert r.context['queryset'].filter(name='Jim').exists()
Proper notification triggered:
trigger_data = json.loads(r.headers['HX-Trigger']) assert trigger_data['notify']['message'] == 'Success!'
DB Side effects:
assert Author.objects.filter(name='Jim').exists()
Workflow: Create HttpRequest instance
Use
rffixture provided bypytest-django:test_r(rf): request = rf.post('no-need-to-have-url', data={'hello': 'yes'})