Search code examples
pythondjangocoverage.pydjango-3.1

Coverage wrongly reports for Django rest framework


I tried to create simple api with Django Rest Framework and use structure like in book Two Scopes of Django 3.x. I tried to create simple test and coverage reports almost 100% coverage on all python sources in my app. Even if I completely remove that test. I tried pytest, nose, and anything what I found here and still same results.

My project structure is following:

.
├── api
│   ├── apps.py
│   ├── __init__.py
│   ├── urls.py
│   └── v1
│       ├── admin.py
│       ├── __init__.py
│       ├── migrations
│       ├── models.py
│       ├── serializers.py
│       ├── tests
│       │   ├── __init__.py
│       │   ├── test_api.py
│       │   ├── test_models.py
│       │   ├── test_serializers.py
│       │   └── test_views.py
│       ├── urls.py
│       └── views.py
├── config
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings
│   │   ├── base.py
│   │   ├── dev.py
│   │   ├── __init__.py
│   │   ├── production.py
│   │   └── test.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── README.md
├── requirements
│   ├── base.txt
│   ├── dev.txt
│   ├── production.txt
│   └── test.txt
└── venv

I also tried to modify manage.py with following changes:

    is_testing = 'test' in sys.argv
    if is_testing:
        import coverage
        cov = coverage.coverage(source=['api'], omit=['*/tests/*'])
        cov.erase()
        cov.start()
    execute_from_command_line(sys.argv)

    if is_testing:
        cov.stop()
        cov.save()
        cov.report()

but this also not helped.

here is an example result of coverage:

(venv) ➜  project ./manage.py test
System check identified no issues (0 silenced).

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK
Name                                Stmts   Miss  Cover
-------------------------------------------------------
api/__init__.py                         0      0   100%
api/apps.py                             3      3     0%
api/urls.py                             2      0   100%
api/v1/__init__.py                      0      0   100%
api/v1/admin.py                         4      0   100%
api/v1/migrations/0001_initial.py      10     10     0%
api/v1/migrations/__init__.py           0      0   100%
api/v1/models.py                       38      3    92%
api/v1/serializers.py                  23      0   100%
api/v1/urls.py                         10      0   100%
api/v1/views.py                        19      0   100%
-------------------------------------------------------
TOTAL                                 109     16    85%

and test is:

from django.urls import reverse
from rest_framework import status

from rest_framework.test import APITestCase
from rest_framework_simplejwt.tokens import RefreshToken

from api.v1.models import User


class BrandTests(APITestCase):
    def setUp(self) -> None:
        self.user = User.objects.create(username='testUser', password='testPass')
        self.token = RefreshToken.for_user(self.user).access_token
        self.client.credentials(HTTP_AUTHORIZATION='JWT ' + str(self.token))

    def test_create_brand(self):
        """
        Ensure that we can create brand
        """
        url = reverse('brand-list')
        response = self.client.get(url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)

EDIT: I created simple app in django and I am getting same result. So it is not caused by project structure neither of combination django+djangorestframework

Does someone face to same issue?


Solution

  • Remember that importing a module will run all of the top-level statements of the module. So just importing a module will cover 100% of the import/class/def lines in that module. If you start with a nearly empty project, most of the lines in it will be those kinds of lines, and the coverage will be very high.