7

Running into a small problem with some code coverage using nosetests and coverage with a Django web application. I have created a .coveragerc file to exclude a huge amount of code (things like class declarations) but I'm still getting some weird results.

Here is my .coveragerc file:

[run]
omit = ../*migrations*, ../*admin.py

[report]
show_missing = True
exclude_lines =
         pragma: no cover
         from
         = models\.

This is an example of one of the models.py files:

from django.db import models

class Query(models.Model):
    variable1 = models.CharField(max_length=100)
    variable2 = models.CharField(max_length=100)
    variable3 = models.CharField(max_length=100)
    variable4 = models.CharField(max_length=100)
    variable5 = models.CharField(max_length=100)
    id = models.AutoField(primary_key=True)

def some_function(self):
     self.variable1 = self.variable2 + self.variable3 + self.variable4 + self.variable 5
     return self.variable1

So when I run code coverage, the issue I run into is that despite me telling coverage to explicitly exclude anything with the string "= models.", it still says the lines are missing in the report given through the command line. This is making it very hard to determine which lines I'm actually failing to cover in my test cases. Can anyone offer some insight to this?

Michael Platt
  • 1,297
  • 12
  • 25
  • How can you be running your tests, and not running the model definition lines? If coverage says they aren't being run, then you are probably running coverage wrong, and it is starting measurement too late. Your attempt to exclude "from" is another sign of the same problem. Don't try to exclude those line. Run coverage earlier. See this answer: http://stackoverflow.com/a/30653523/14343 – Ned Batchelder Jul 30 '16 at 10:04
  • Ok so that fixed the problem. I appreciate the link to the other question. – Michael Platt Aug 01 '16 at 14:27

2 Answers2

1

Your .coveragerc file should list things to exclude starting from the root of your directory.

For example:

proj
|-- app1
   |
   -- models.py
   -- migrations.py
|-- app2

Then your coverage.rc file should look like:

[run]
omit = app1/migrations.py, app1/admin.py

or

[run]
omit = proj/*/migrations.py, proj/*/admin.py
David Buck
  • 3,752
  • 35
  • 31
  • 35
Alex
  • 1,432
  • 14
  • 26
  • So the problem isn't with the omit. The problem is with the "exclude_lines" part of the file. I'm getting a low percentage of code coverage because I'm not technically testing any of my variable declarations (which i don't want to test). That's why in the "exclude_lines" I added " = models/." I don't want coverage.py to recognize these lines of codes as something needing testing. I hope I'm explaining this in a way that makes sense but I'm not sure how else to word it. – Michael Platt Jul 29 '16 at 20:38
  • Ah so you want to test the methods on the models, but not the actual model itself? I'm not sure you can discriminate between the two in the coveragerc file. You might have to move the model methods into another file and keep the models untested. – Alex Jul 29 '16 at 20:41
  • Yeah I was hoping I could avoid doing that with the regex stuff in the exclude_lines since Django technically says to include the functionality for the models in the actual models. I guess we could technically not adhere to the Django standards but I feel as though the methods would be more convoluted if we went down that path. – Michael Platt Jul 29 '16 at 20:47
  • Yeah, personally I would keep the methods in the models.py file. Might have to sacrifice code coverage for best practices. – Alex Jul 29 '16 at 20:50
  • Only problem with that is the code coverage is a whole 8% haha. There aren't a ton of methods in the models.py but there are a ton of variable declarations and I don't know how good it will look to customers in the event we say there is an 8% code coverage, even if we explain why it's so low :-/ – Michael Platt Jul 29 '16 at 20:53
  • You could also add [`#pragma: no cover`](http://coverage.readthedocs.io/en/coverage-4.0.3/excluding.html) to the definitions of the models. – Alex Jul 29 '16 at 20:56
  • I've thought about that as well and while I could if I can avoid blocks of code instead of doing line by line I would like to. The sample code posted is a very simple example. I have about 8 or 9 models right now that each have over 10 attributes. That would be a lot of comments just for code coverage. – Michael Platt Jul 29 '16 at 21:21
  • I believe you can use one `#pragma: no cover` per object, so it would only be a 8 or 9 of them. Might be worth it? – Alex Jul 29 '16 at 22:21
  • Yeah I could go down that road but I feel as though it's a very inelegant solution to the problem. Not to mention I'm then introducing "testing code" into the main application which doesn't feel right to me. – Michael Platt Aug 01 '16 at 13:55
0

Found the solution to my problem. It turns out I don't need to use nosetests at all. I can simply run the coverage.py with manage.py test and pass in the test modules. The code coverage worked great and I'm up to 96% coverage :-)

Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
Michael Platt
  • 1,297
  • 12
  • 25