Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python coverage.py exclude_lines

Background

I have a couple Django projects that I use coverage.py with and have been trying to add some additional expressions to the exclude_lines portion of my .coveragerc configuration file. The problem is that even with proper regex that works at picking up the line in a tester such as http://www.pythonregex.com or http://www.regexr.com it doesn't result in the lines being ignored in the report.

I've reviewed the docs and poked around the repository but haven't been able to dig up any reasoning to why the config I have might not be working. From the docs it appears I have the config exactly as they describe it should be.

I've also attempted to use django-nose version 1.2, the last PyPI release, which would allow exception injection but to no avail, it appears to have some issues with figuring out the coverage of Django views and Django REST Framework API endpoints at least in version 1.7.

What I've Tried

My configuration is as follows:

[run]
branch = True
omit =
    */tests*
    */migrations/*
    *__init__.py*
    */settings/*
    *wsgi.py*
    *admin.py*

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
    pragma: no cover
    def __repr__
    if self.debug:
    raise AssertionError
    raise NotImplementedError
    (.*)except Exception as e:(.*)
    if 0:
    if __name__ == .__main__.:

I've also tried the following combinations for the exception handling in the report section of the config:

(.*)except Exception as e:
except Exception as e:
except Exception as e:(.*)

An example of a function with the portion of code I expect to be ignored is below:

def my_func():
    try:
        # Some logic
        return True
    except Exception as e:
        return defensive_exception(my_func.__name__, e, False)

In the above example, based on the documentation, I would expect everything under the except Exception as e: to be ignored or at least the except Exception as e line itself. However this doesn't appear to be the case. If anyone has some insight into what is wrong with my configuration or what I need to do differently I would greatly appreciate the help.

like image 977
devonbleibtrey Avatar asked Nov 21 '14 15:11

devonbleibtrey


2 Answers

You do not need to match the entire line, so there is no need for the dot-stars at the end. This should work:

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
    pragma: no cover
    def __repr__
    if self.debug:
    raise AssertionError
    raise NotImplementedError
    except Exception as e:

THAT SAID: this style of coding concerns me a great deal. Catching blanket exceptions as you are doing is bad style and can hide problems. Then you seem to not care if that code is tested!

If you need to perform strong exception handling across a large number of functions like this, perhaps you want to write a function decorator to wrap the function call. That will reduce the number of lines of code, and centralize your logic. Then you can deal with the coverage issues in one place also.

like image 199
Ned Batchelder Avatar answered Sep 17 '22 07:09

Ned Batchelder


What I always do is use pragma: no cover for this which you already have in your exclude_lines.

def my_func():
    try:
        # Some logic
        return True
    except Exception as e:  # pragma: no cover
        return defensive_exception(my_func.__name__, e, False)
like image 29
Wolph Avatar answered Sep 18 '22 07:09

Wolph