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

    , , , , , , , ,

    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.

    loading