Skip to content

Miscellaneous

Admin

We can use a helper from pytest-django called admin_client, [https://pytest-django.readthedocs.io/en/latest/helpers.html#admin-client-django-test-client-logged-in-as-admin][https://pytest-django.readthedocs.io/en/latest/helpers.html#admin-client-django-test-client-logged-in-as-admin]

def test_an_admin_view(admin_client):
    response = admin_client.get('/admin/')
    assert response.status_code == 200
There are some admin tests in 05_misc using both pytest and testcase.

In the Django source, there is an extensive set of tests.

We can learn a lot from this, for example the testing of Django Amdin Forms: https://github.com/django/django/blob/main/tests/forms_tests/tests/test_forms.py.

as well as forms in general: https://github.com/django/django/blob/main/tests/forms_tests/tests/test_forms.py.

Middleware

This is based on Middleware UnitTest using UnitTest with additonal PyTest version based on Middleware PyTest.

We make use of override settings faciltiy in Django, docs, and we can use a decorator:

It can prove unwieldy to redefine settings that contain a list of values. In practice, adding or removing values is often sufficient. Django provides the modify_settings() context manager for easier settings changes, as the context manager will enable automatic resetting.

# locallibrary/middleware.py

"""Middleware for locallibrary project.
Based on BugBytes https://www.youtube.com/watch?v=TTEEr4N-lKw&t
"""

from django.http import HttpResponse
from django.shortcuts import render
from django.conf import settings
from rich.console import Console

console = Console()


class MaintenanceModeMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        console.log("[green]Request Received[/]")
        if settings.MAINTENANCE_MODE:
            console.log("[red bold]Application is in maintenance mode![/]")
            # return HttpResponse("Application is in maintenance mode!")
            return render(request, "maintenance_mode_on.html")

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

In settings.py we add:

MAINTENANCE_MODE = False to turn maintenance mode on/off and we add to the list of middlewares:

MIDDLEWARE = [
   ...
    "locallibrary.middleware.MaintenanceModeMiddleware",
]

The tests can be found in 05_misc\test_maintenance_mode.py, (pytest) and 05_misc\test_maintenance_mode_simple_testcase.py, (SimpleTestCase as we don't need DB access and will thus be a quicker test).

# 05_misc/test_maintenance_mode_simple_testcase.py

from django.test import SimpleTestCase, Client, override_settings

# We cannot use RequestFactory as RF does not use middleware


class MaintenanceModeMiddlewareTest(SimpleTestCase):

    def setUp(self):
        self.client = Client()

    @override_settings(MAINTENANCE_MODE=True)
    def test_MSC_501_response_when_maintenance_mode_is_on_simple_test_case(self):
        response = self.client.get("/")
        print(response)
        self.assertContains(response, "maintenance mode")
        self.assertTemplateUsed(response, "maintenance_mode_on.html")

    @override_settings(MAINTENANCE_MODE=False)
    def test_MSC_502_response_when_maintenance_mode_is_off_simple_test_case(self):
        response = self.client.get("/")
        print(response)
        self.assertTemplateNotUsed(response, "maintenance_mode_on.html")

To turn on: MAINTENANCE_MODE = True in settings.py

As we are not using the DB we can use SimpleTestCase.

Template tags/filters

Signals

There are no signals tests in this app but a useful article explains how to use context managers to deal with the asyncronicity of signal testing:

https://www.bomberbot.com/python/how-to-test-django-signals-like-a-pro/

https://python.plainenglish.io/five-ways-to-test-django-signals-9f3643664d2d