Setting up tests for Django Plugins


Did you have a good idea for a nice Django plugin? Don’t know how to set up tests for it without creating a whole Django app for your project? Here is the solution for you. This article is written after a pull request for Django Public Admin, using django-stdimage as a base.

Django Public Admin is a plugin that makes a public and read-only version of the Django Admin. It uses Poetry to manage packages and dependencies, pytest to run tests in addition to pytest-django.

What is Django

Django is a web framework written in Python, and it’s designed for developers to write reusable apps (apps in this context means application, which in this case is the project designed using Django):

“Reusability is the way of life in Python. […] Django itself is also a normal Python package. This means that you can take existing Python packages or Django apps and compose them into your own web project. You only need to write the parts that make your project unique. The idea of these apps.”

In other words, we can wrap reusable parts of any Django app and use them in other Django apps we write. This is the idea and for that we also need tests. At the end of the day, we have a reusable bit of code without the accompanying Django application.

So, how to test a part of a Django app without the full Django app? 🤔

Understanding what is missing

With the environment already configured, the first issue that appeared was that when running the tests outside of a Django app was that it was complaining that our Django was ImproperlyConfigured and that we need to set up the DJANGO_SETTINGS_MODULE:

You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

Setting up tests/settings.py

After talking to Ana Paula Gomes, she pointed out that she already saw this being implemented in a nice way on another project, and what was being made was to create a tests/settings.py file that will act as configuration for Django to run the tests. So for that, I created a file that looks like that:

import os

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'public_admin',
    'tests'
)

SECRET_KEY = 'foobar'

It does contain the default Django configuration variables as below:

  • BASE_DIR: This is pointed to the Django project directory.

  • INSTALLED_APPS: Which contains all the apps necessary to run your set up (don’t forget to add your project here public_admin in our target project, and tests ), and might vary depending on what you are testing.

  • SECRET_KEY: The SECRET_KEY setting must not be empty.

Setting up setup.cfg

After configuring up the settings.py we need to tell our application to use this file to run the tests, setting up the DJANGO_SETTINGS_MODULE variable in a special file called setup.cfg, in our case, we tell that when [tool:pytest] is called we should use this settings environment, this might look like that:

[tool:pytest]
DJANGO_SETTINGS_MODULE=tests.settings

And that is it, now you can set up your tests for Django Plugins without creating an app for testing using pytest.