How to measure test coverage in Django

Wednesday, September 18, 2024 at 2:10 PM | 3 min read

Last modified on Saturday, June 13, 2026 at 11:37 PM

#command line, #terminal, #fullstack development, #macOS, #django, #python3, #tests, #coverage, #coverage.py

Man Holding Microphone While Talking to Another Man
and covering a story

Photo by Mido Makasardi on pexels.com

Table of Contents

What is test coverage in Django?

When we have written some tests for our Django applications, we might wonder whether or not we wrote enough tests and for the right things. One way we can determine this is by measuring the coverage of our tests. In other words, how thoroughly our tests encompass our application's code.

Tools for measuring coverage in Django

Probably the most popular tool for measuring coverage in Python is the Coverage.py tool. It monitors Python programming, noting which parts of the code have been executed, then analyzes the source to identify code that could have been executed but was not.

Installing Coverage.py

To install coverage.py, run the command below in the root directory of your project (in my case, the django-boards directory (as opposed to django*boards directory)) where the venv directory resides. Also make sure that your virtual environment has been activated before installing the coverage package.

python3 -m pip install coverage

The C extension

According to Coverage.py,

Coverage.py includes a C extension for speed. It is strongly recommended to use this extension: it is much faster, and is needed to support a number of coverage.py features. Most of the time, the C extension will be installed without any special action on your part.

I did not need to add a C extension to coverage.py. And I didn't need to do any configuration.

Checking for coverage's version

In order to find out what version of coverage we have installed, we can run the following command in Terminal inside our Django project with venv activated:

coverage --version

When I ran coverage --version at the django-boards root directory, I got back the following:

Coverage.py, version 7.6.1 with C extension Full documentation is at https://coverage.readthedocs.io/en/7.6.1

My coverage installation does come with the C extension.

Running the coverage command

In order to implement Coverage.py, we run the following command in the directory where our manage.py file resides:

coverage run manage.py test

This command will include ALL our project tests: both in accounts and boards.

Coverage report

After running coverage run manage.py test, we can generate a coverage report with the following command in the same directory:

coverage report

For me, the following report was generated:

NameStmtsMissCover
accounts/__init__.py00100%
accounts/admin.py10100%
accounts/apps.py40100%
accounts/forms.py80100%
accounts/migrations/__init__.py00100%
accounts/models.py10100%
accounts/tests/__init__.py00100%
accounts/tests/test_invalid_signup_tests.py170100%
accounts/tests/test_signup_tests.py270100%
accounts/tests/test_successful_signup_tests.py200100%
accounts/tests/test_view_signup.py00100%
accounts/views.py120100%
boards/__init__.py00100%
boards/admin.py60100%
boards/apps.py40100%
boards/forms.py70100%
boards/migrations/0001_initial.py70100%
boards/migrations/0002_post_post_liked_topic_topic_liked_postlike_topiclike.py60100%
boards/migrations/0003_remove_topic_topic_liked_delete_topiclike.py40100%
boards/migrations/0004_alter_postlike_post_like_value.py40100%
boards/migrations/0005_alter_postlike_post_like_value.py50100%
boards/migrations/0006_alter_postlike_post_like_value.py40100%
boards/migrations/0007_remove_post_post_liked_post_post_liked_by.py50100%
boards/migrations/0008_alter_post_post_liked_by.py50100%
boards/migrations/0009_alter_post_post_liked_by.py50100%
boards/migrations/__init__.py00100%
boards/models.py34585%
boards/templatetags/form_tags.py16288%
boards/tests/__init__.py00100%
boards/tests/test_board_topics_tests.py280100%
boards/tests/test_index_tests.py250100%
boards/tests/test_new_topic_tests.py280100%
boards/tests/test_templatetags.py240100%
boards/views.py240100%
django_boards/__init__.py00100%
django_boards/settings.py260100%
django_boards/urls.py60100%
manage.py11282%
TOTAL374998%

Coverage html

If I want to generate an html document of my coverage report (produce annotated HTML listings with coverage results), I can run coverage html in Terminal, and the following is returned:

Wrote HTML report to htmlcov/index.html

I add the htmlcov directory to my .gitignore file, and I also add the .coverage file that was created when I ran coverage run manage.py test.

Conclusion

In this post, I went over the basics of Coverage.py and how to determine the percentage of a Django application my tests have covered using the coverage command. There is much more to Coverage.py, and more Command Line usage available, but this is a great start.