Skip to main content

A coverage.py plugin to measure test coverage of Django templates.

Package stability Latest PyPI Version Apache 2.0 License
Supported Python Versions Supported Django Versions
Sponsor me on GitHub nedbat on Bluesky nedbat on Mastodon

Supported on:

  • Python: 3.10 through 3.14.

  • Django: 5.2 through 6.0.

  • Coverage.py: 6.x or higher.

The plugin is pip-installable:

$ python3 -m pip install django_coverage_plugin

To run it, add this setting to your .coveragerc file:

[run]
plugins = django_coverage_plugin

Then run your tests under coverage.py.

You will see your templates listed in your coverage report along with your Python modules.

If you get a django.core.exceptions.ImproperlyConfigured error, you need to set the DJANGO_SETTINGS_MODULE environment variable.

Template coverage only works if your Django templates have debugging enabled. If you get django_coverage_plugin.plugin.DjangoTemplatePluginException: Template debugging must be enabled in settings, or if no templates get measured, make sure you have TEMPLATES.OPTIONS.debug set to True in your settings file:

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'debug': True,
        },
    },
]

Configuration

The Django template plugin uses some existing settings from your .coveragerc file. The source=, include=, and omit= options control what template files are included in the report.

The plugin can find unused template and include them in your results. By default, it will look for files in your templates directory with an extension of .html, .htm, or .txt. You can configure it to look for a different set of extensions if you like:

[run]
plugins = django_coverage_plugin

[django_coverage_plugin]
template_extensions = html, txt, tex, email

If you use pyproject.toml for tool configuration use:

[tool.coverage.run]
plugins = [
    'django_coverage_plugin',
]

[tool.coverage.django_coverage_plugin]
template_extensions = 'html, txt, tex, email'

Caveats

Coverage.py can’t tell whether a {% blocktrans %} tag used the singular or plural text, so both are marked as used if the tag is used.

What the? How?

The technique used to measure the coverage is the same that Dmitry Trofimov used in dtcov, but integrated into coverage.py as a plugin, and made more performant. I’d love to see how well it works in a real production project. If you want to help me with it, feel free to drop me an email.

The coverage.py plugin mechanism is designed to be generally useful for hooking into the collection and reporting phases of coverage.py, specifically to support non-Python files. If you have non-Python files you’d like to support in coverage.py, let’s talk.

Tests

To run the tests:

$ python3 -m pip install -r requirements.txt
$ tox

Authors

The Django coverage plugin was written by Ned Batchelder, with contributions by:

  • Andrew Pinkham

  • Aron Griffis

  • Bruno Alla

  • Emil Madsen

  • Federico Bond

  • Jessamyn Smith

  • Marc Gibbons

  • Pamela McA’Nulty

  • Simon Charette

History

v3.2.2 — 2026-04-04

Fix: {% endblock %} lines (and others) were falsely reported as unexecuted when they appeared on their own indented line (issue 74). Thanks, Marc Gibbons (pull 108).

Dropped Django 3.x and 4.x.

Switched to trusted publishing.

v3.2.0 — 2025-10-05

Drop Python 3.9 and Django 2.2. Add Python 3.14.

v3.1.1 — 2025-06-15

Support changes: dropped Python 3.8, added Python 3.13. Added Django 5.2.

v3.1.0 — 2023-07-10

Dropped support for Python 3.7 and Django 1.x. Declared support for Python 3.12.

v3.0.0 — 2022-12-06

Dropped support for Python 2.7, Python 3.6, and Django 1.8.

v2.0.4 — 2022-10-31

Declare our support for Python 3.11 and Django 4.1.

v2.0.3 — 2022-05-04

Add support for Django 4.0.

v2.0.2 — 2021-11-11

If a non-UTF8 file was found when looking for templates, it would fail when reading during the reporting phase, ending execution. This failure is now raised in a way that can be ignored with a .coveragerc setting of [report] ignore_errors=True (issue 78).

When using source=., an existing coverage HTML report directory would be found and believed to be unmeasured HTML template files. This is now fixed.

v2.0.1 — 2021-10-06

Test and claim our support on Python 3.10.

v2.0.0 — 2021-06-08

Drop support for Python 3.4 and 3.5.

A setting is available: template_extensions lets you set the file extensions that will be considered when looking for unused templates (requested in issue 60).

Fix an issue on Windows where file names were being compared case-sensitively, causing templates to be missed (issue 46).

Fix an issue (issue 63) where tag libraries can’t be found if imported during test collection. Thanks to Daniel Izquierdo for the fix.

v1.8.0 — 2020-01-23

Add support for:

  • Coverage 5

v1.7.0 — 2020-01-16

Add support for:

  • Python 3.7 & 3.8

  • Django 2.2 & 3.0

v1.6.0 — 2018-09-04

Add support for Django 2.1.

v1.5.2 — 2017-10-18

Validates support for Django version 2.0b1. Improves discovery of template files.

v1.5.1a — 2017-04-05

Validates support for Django version 1.11. Testing for new package maintainer Pamela McA’Nulty

v1.5.0 — 2017-02-23

Removes support for Django versions below 1.8. Validates support for Django version 1.11b1

v1.4.2 — 2017-02-06

Fixes another instance of issue 32, which was the result of an initialization order problem.

v1.4.1 — 2017-01-25

Fixes issue 32, which was the result of an initialization order problem.

v1.4 — 2017-01-16

Django 1.10.5 is now supported.

Checking settings configuration is deferred so that settings.py is included in coverage reporting. Fixes issue 28.

Only the django.template.backends.django.DjangoTemplates template engine is supported, and it must be configured with ['OPTIONS']['debug'] = True. Fixes issue 27.

v1.3.1 — 2016-06-02

Settings are read slightly differently, so as to not interfere with programs that don’t need settings. Fixes issue 18.

v1.3 — 2016-04-03

Multiple template engines are allowed. Thanks, Simon Charette.

v1.2.2 — 2016-02-01

No change in code, but Django 1.9.2 is now supported.

v1.2.1 — 2016-01-28

The template debug settings are checked properly for people still using TEMPLATE_DEBUG in newer versions of Django.

v1.2 — 2016-01-16

Check if template debugging is enabled in the settings, and raise a visible warning if not. This prevents mysterious failures of the plugin, and fixes issue 17.

Potential Django 1.9 support is included, but the patch to Django hasn’t been applied yet.

v1.1 — 2015-11-12

Explicitly configure settings if need be to get things to work.

v1.0 — 2015-09-20

First version :)

Release files for django-coverage-plugin 3.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-coverage-plugin 3.2.2
File Size Uploaded
django_coverage_plugin-3.2.2.tar.gz 30.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-coverage-plugin 3.2.2
File Interpreter ABI Platform
django_coverage_plugin-3.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 45.3 kB

Release files / django_coverage_plugin-3.2.2.tar.gz

Download URL django_coverage_plugin-3.2.2.tar.gz
Size 30.8 kB
Tags Source
SHA-256 checksum
How to use checksums
fcc507ee02f3a8f7c1d79b6eba1bafebb4a95b5055801987b715f4f88270c441
BLAKE2b-256 checksum
How to use checksums
7607c3814563d63b8680f4d5bb8880bb151039e258e7d91a7867b0eaf45165bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 4, 2026.

Transparency log

Release files / django_coverage_plugin-3.2.2-py3-none-any.whl

Download URL django_coverage_plugin-3.2.2-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
66c9bdb2756762d6bef3510548bb228e1e8465ff1cd2b372775b82624e85e0b4
BLAKE2b-256 checksum
How to use checksums
43ae981522be2a8c46eebdd70debcbb2b0e55a8dbd44a3034c727e298b2ba129
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.2.2 This release

2 release files

3.2.0

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

1 release file

2.0.0

1 release file

1.8.0

1 release file

1.7.0

1 release file

1.6.0

1 release file

1.5.0

1 release file

1.4.2

1 release file

1.4.1

1 release file

1.4

1 release file

1.3.1

1 release file

1.3

1 release file

1.2.2

1 release file

1.2.1

1 release file

1.2

1 release file

1.1

1 release file

1.0

1 release file

1.0b1

0.6

1 release file

0.5

1 release file

0.3.3

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3

1 release file

0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page