0

I am using coverage in the following way to test my django app:

 DJANGO_SETTINGS_MODULE=$(SETTINGS) coverage run manage.py test -v 2
 DJANGO_SETTINGS_MODULE=$(SETTINGS) coverage report

In my test suite I tests some views:

class TestJSON(TestCase):

    def setUp(self):
        self.client.login(username='admin', password='passwordz')

    def test_bookmarks_json(self):
        translator = User.objects.create_user('normaluser', 'foobar@test.com',
                                              'secretz')
        search = SearchBookmark(
            search="minutes")
        search.save()
        response = self.client.get('/bookmarks_json/')
        ans = json.loads(response.content)[0]
        self.assertEqual(...)

So I am clearly hitting everything defined in that view for '/bookmarks_json/'. Never the less coverage report says that the signature line is not hit, e.g.:

@login_required
def bookmarks_as_json(request):
    bookmarks = SearchBookmark.objects.all()
    data = serializers.serialize("json", bookmarks)
    return HttpResponse(data, content_type='application/json')

I have seen the solution by Ned Batchelder here Django coverage test for URLs 0%, why? and I am guessing it is some how related. As a result I wrote my own test runner:

import os
import sys
import django
from django.conf import settings
from django.test.utils import get_runner

if __name__ == "__main__":
    os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings.dev'
    django.setup()
    TestRunner = get_runner(settings)
    test_runner = TestRunner(verbosity=2)
    failures = test_runner.run_tests(["myapp.tests"])
    sys.exit(bool(failures))

And

   python testrunner.py   # works, def in view.py is reported !

However, I would like to use the normal command ./manage.py test so I was wondering if there is a way to fix this, with out writing my own test runner.

Community
  • 1
  • 1
oz123
  • 27,559
  • 27
  • 125
  • 187

1 Answers1

0

The real issue with your test seems to be that you do not log in before testing the view. Since the view uses the login_required decorator, the client is redirected, the view doesn't run, so it will show as missing in the coverage report.

You can log in using self.client.login() before your self.client.get() call.

translator = User.objects.create_user('normaluser', 'foobar@test.com',
                                      'secretz')
search = SearchBookmark(
    search="minutes")
search.save()
self.client.login(username='normaluser', password='secretz')
response = self.client.get('/bookmarks_json/')
ans = json.loads(response.content)[0]
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • That is not the issue. What you don't see, is that my `setUp` method does the login. I'm also checking that the content delivered is fine. – oz123 Mar 29 '16 at 14:45
  • OK, you didn't show your setUp method at first, so we couldn't see that you had logged in. I'll delete this answer now. – Alasdair Mar 29 '16 at 14:59