zero-config pytest plugin that runs generic safety checks on any Django project.
Project description
pytest-django-autocheck
Zero-config pytest plugin that runs generic safety checks on any Django project. .
Pulls in pytest-django automatically
and discovers Django settings from your manage.py. Install and run:
pip install pytest-django-autocheck
pytest --autocheck
Why
Legacy or untested Django projects rarely have any safety net. This plugin catches the basics in CI before they reach production:
- modules that fail to import
- migrations that don't reverse, or are missing entirely
- models that can't be saved or stringified
- admin pages that return 500/404
- broken URLconfs
- public pages that return 500
- template syntax errors
- management commands that fail to load
- forms and serializers that can't be instantiated
- Django system check failures
Requirements
- Python 3.10+
- Django 5.0+
Installation
pip install pytest-django-autocheck
Usage
From your project root (where manage.py lives):
pytest --autocheck
The plugin discovers DJANGO_SETTINGS_MODULE from manage.py. If you already
declare it explicitly (in pytest.ini/pyproject.toml, via --ds, or as an
environment variable), that value wins and auto-discovery is skipped.
Run only specific checks by repeating --autocheck-only:
# a single check
pytest --autocheck --autocheck-only=admin
# multiple checks
pytest --autocheck --autocheck-only=admin --autocheck-only=models
Or skip specific checks with --autocheck-skip:
pytest --autocheck --autocheck-skip=templates --autocheck-skip=serializers
Both flags can be combined; --autocheck-skip is applied after
--autocheck-only, so a check named in both ends up skipped.
Valid check names for both flags: admin, forms, imports,
management_commands, migrations, models, serializers, system_checks,
templates, urls, views.
Checks
| Check | Description |
|---|---|
admin |
Every admin registered for a project model validates its configuration and renders its changelist and changeform without 500/404. Admins for third-party models are skipped. |
forms |
Every ModelForm defined in a project app's forms module instantiates without raising. |
imports |
Every module of every project app imports without ImportError or circular import (third-party pip apps are skipped). |
management_commands |
Every management command defined by a project app loads its class and builds its argument parser without raising. |
migrations |
Detects model changes not captured by a migration, statically inspects every project migration for irreversible operations and silent noop-reverse migrations, then dynamically verifies the whole graph by applying it forward, reversing to zero, and re-applying forward on a throwaway database. Third-party and django.contrib migrations are skipped: a dependency's irreversible data migration won't fail your build. |
models |
Every project model is instantiable, savable, and stringifiable via both str() and repr(). Third-party and django.contrib models are skipped. |
serializers |
Every Django REST Framework serializer defined in a project app (<app>.serializers or <app>.api.serializers) binds its fields without raising. Skipped entirely when djangorestframework isn't installed. |
system_checks |
Runs Django's own system check framework (django.core.checks) and reports every error, warning and info message it raises. |
templates |
Every template under the project's own template directories compiles without a TemplateSyntaxError. |
urls |
Every URL pattern loads its included URLconf, resolves its callback, and reverses without raising (other than NoReverseMatch). |
views |
Every named URL that reverses without arguments and whose view is owned by a project app is requested with GET by an unauthenticated client; a raised exception or an HTTP 5xx response is reported. Anything below 500 (redirects, 403, 404) is a legitimate answer for an anonymous client and is ignored. Views shipped by third-party packages are skipped (ownership is resolved from the view callback's module, for both function-based and class-based views), and the admin namespace is skipped because the admin check already exercises it with a superuser. |
Settings
Every option is read from Django settings under the
PYTEST_DJANGO_AUTOCHECK_ prefix, with a safe default: override only what
you need.
| Setting | Default | Effect |
|---|---|---|
PYTEST_DJANGO_AUTOCHECK_CHECKS |
None |
List of check names to run, e.g. ["imports", "migrations"]. When unset, every registered check runs. --autocheck-only, when given, takes precedence. |
PYTEST_DJANGO_AUTOCHECK_SKIP |
None |
List of check names to exclude, e.g. ["templates", "serializers"]. Applied after CHECKS/--autocheck-only. --autocheck-skip, when given, takes precedence. |
PYTEST_DJANGO_AUTOCHECK_MIGRATIONS_PROBE_TIMEOUT |
300 |
Max seconds the dynamic migration probe subprocess may run before it's aborted; on timeout the dynamic step is skipped with a WARNING and the run doesn't fail. The probe self-aborts at this deadline and destroys its throwaway database. |
PYTEST_DJANGO_AUTOCHECK_DEPLOY |
False |
When True, system_checks also runs Django's deployment checks (DEBUG, SECRET_KEY, SSL/HSTS, secure cookies). Off by default since those fail on dev/test settings; enable for a pre-production audit. |
The dynamic migration verification runs in a short-lived subprocess, isolated from the suite's own test database. If that subprocess can't set up its environment, the dynamic step is skipped with a warning rather than failing the run.
Instance generation
The models and admin checks need a valid instance of every model. The
generator prefers the project's own factory_boy factories when present
(looked up in <app>.factories or <app>.tests.factories): they already
encode domain rules, which avoids false positives. Falls back to
model_bakery when no factory is found.
factory_boy is optional; discovery is a no-op if it's not installed.
The serializers check requires
Django REST Framework and is skipped
if it's not installed.
Testing
# clone repository
git clone https://github.com/fabiocaccamo/pytest-django-autocheck.git && cd pytest-django-autocheck
# create virtualenv and activate it
python -m venv .venv && . .venv/bin/activate
# upgrade pip
python -m pip install --upgrade pip
# install package and test requirements
python -m pip install -e ".[test]"
# install pre-commit to run formatters and linters
pre-commit install --install-hooks
# run tests using tox
tox
# or run tests using pytest
coverage run -m pytest && coverage report -m
License
Released under MIT License.
Supporting
- :star: Star this project on GitHub
- :octocat: Follow me on GitHub
- :blue_heart: Follow me on Bluesky
- :moneybag: Sponsor me on Github
See also
-
django-admin-interface- the default admin interface made customizable by the admin itself. popup windows replaced by modals. 🧙 ⚡ -
django-cache-cleaner- clear the entire cache or individual caches easily using the admin panel or management command. 🧹✨ -
django-colorfield- simple color field for models with a nice color-picker in the admin. 🎨 -
django-email-validators- no more invalid or disposable emails in your database. ✉️ ✅ -
django-extra-settings- config and manage typed extra settings using just the django admin. ⚙️ -
django-maintenance-mode- shows a 503 error page when maintenance-mode is on. 🚧 🛠️ -
django-redirects- redirects with full control. ↪️ -
django-treenode- probably the best abstract model / admin for your tree based stuff. 🌳 -
python-benedict- dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities. 📘 -
python-codicefiscale- encode/decode Italian fiscal codes - codifica/decodifica del Codice Fiscale. 🇮🇹 💳 -
python-fontbro- friendly font operations. 🧢 -
python-fsutil- file-system utilities for lazy devs. 🧟♂️
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_django_autocheck-0.1.0.tar.gz.
File metadata
- Download URL: pytest_django_autocheck-0.1.0.tar.gz
- Upload date:
- Size: 47.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cea2dfaccabcb53a84bf077883131aed49cb51567830ad395902450278ba16f3
|
|
| MD5 |
3dab6b442bece0961849d294dcb260d1
|
|
| BLAKE2b-256 |
bb09675c12b3160896128704e5cc86bdb4943bfa5a4ec991f0e764648f530c53
|
Provenance
The following attestation bundles were made for pytest_django_autocheck-0.1.0.tar.gz:
Publisher:
create-release.yml on fabiocaccamo/pytest-django-autocheck
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_django_autocheck-0.1.0.tar.gz -
Subject digest:
cea2dfaccabcb53a84bf077883131aed49cb51567830ad395902450278ba16f3 - Sigstore transparency entry: 2108792175
- Sigstore integration time:
-
Permalink:
fabiocaccamo/pytest-django-autocheck@d9699482c3e74ef311bb66a20b5b73ddda9e377f -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/fabiocaccamo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
create-release.yml@d9699482c3e74ef311bb66a20b5b73ddda9e377f -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytest_django_autocheck-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pytest_django_autocheck-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3b44ba76fb872222c87d66fbe7807317b1232c7d785893cf9a8700267ad9012
|
|
| MD5 |
8959b140d106f464662eea7bdee1323e
|
|
| BLAKE2b-256 |
f8716086f0bc3ab87f9648e044fb79e02b876b45eb97152fbe166bd3708bbf50
|
Provenance
The following attestation bundles were made for pytest_django_autocheck-0.1.0-py3-none-any.whl:
Publisher:
create-release.yml on fabiocaccamo/pytest-django-autocheck
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_django_autocheck-0.1.0-py3-none-any.whl -
Subject digest:
d3b44ba76fb872222c87d66fbe7807317b1232c7d785893cf9a8700267ad9012 - Sigstore transparency entry: 2108792353
- Sigstore integration time:
-
Permalink:
fabiocaccamo/pytest-django-autocheck@d9699482c3e74ef311bb66a20b5b73ddda9e377f -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/fabiocaccamo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
create-release.yml@d9699482c3e74ef311bb66a20b5b73ddda9e377f -
Trigger Event:
push
-
Statement type: