Code Monkey home page Code Monkey logo

django-discoverage's Introduction

django-discoverage

Adds coverage to Django 1.6's test runner and Carl Meyer and Jannis Leidel's django-discover-runner.

Inspired by django-coverage.

django-discoverage works with Django 1.4 and above. If you are using Django 1.4 or 1.5, django-discover-runner is required and will be automatically installed. That package backports the implementation of DiscoverRunner included in Django 1.6.

Quick usage

Change TEST_RUNNER in your project settings to enable django-discoverage as the project test runner:

TEST_RUNNER = 'discoverage.DiscoverageRunner'

To run the tests, type:

./manage.py test [options] [appname ...]

To run the tests without code coverage (i.e. run django-discover-runner instead), type:

./manage.py test --no-coverage [options] [appname ...]

If you want to use the --no-coverage option, make sure you add discoverage to your INSTALLED_APPS.

Detailed usage

One of the objectives of Django's DiscoverRunner (previously django-discover-runner) is to allow the separation of a Django app's tests from the code it's testing. Since tests no longer reside in an app, django-discoverage needs a different way to know which apps to include in the coverage report. The runner does this in two ways which are discussed below.

First, it tries to infer which apps you are testing from the name of the package in which the test's module lives. For example, if you have an app blog and you test the view of the app in the module tests.blog.test_views, the app will be included in the coverage report. The same happens if the app is a subpackage and appears in INSTALLED_APPS as myproject.blog.

This behavior is controlled by the PKG_NAME_APP_DISCOVERY setting.

Although not on by default, tested apps can also be guessed from the name of the test's module. For example, if MODULE_NAME_APP_DISCOVERY is True and there is a module named tests.test_blog, the blog app will be included in the report. You can override the regular expression used to extract the app name using the MODULE_NAME_DISCOVERY_PATTERN setting.

The second way in which django-discoverage finds apps is by looking for an iterable of app names (named by default TESTS_APPS) in three places:

  1. On a TestCase instance in the suite.
  2. In the TestCase subclass's module (test*.py by default).
  3. In the TestCase subclass's immediate package. If MyTestCase is in the package tests.myapp.test_views, the runner inspects tests.myapp. It does not currently traverse parent packages.

Let's say you had the following test module, tests.blog.test_views:

TESTS_APPS = ('blog',)

class MyTestCase(TestCase):
    TESTS_APPS = ('mycoolapp', 'myproject.anothercoolapp')
    ...

All modules in the apps blog, mycoolapp, and myproject.anothercoolapp will be included in the report along with any apps listed in test.blog.TESTS_APPS.

Modules specified in OMIT_MODULES will not, however, appear in the report.

Settings

PKG_NAME_APP_DISCOVERY

Determines whether tested apps are guessed from a test module's package name. It is on by default.

MODULE_NAME_APP_DISCOVERY

Determines whether tested apps are guessed from a test module's name.

MODULE_NAME_DISCOVERY_PATTERN

A regular expression with a single capturing group that extracts the app name from a module name (e.g. "blog" from test_blog). Defaults to "test_?(\w+)".

TESTED_APPS_VAR_NAME

The name of the iterable django-discoverage looks for in the three places listed above. Defaults to TESTS_APPS.

COVERAGE_OMIT_MODULES

Modules not to be traced by coverage. See the coverage API documentation for more details. Defaults to ['*test*'].

COVERAGE_EXCLUDE_PATTERNS

A list of regular expressions that impact coverage reporting. If a line of tested code matches one of the patterns in the list, it will not count as a missed line. See the coverage API documentation for more details.

Defaults to:

  • def get_absolute_url(self):
  • def __unicode__(self):
  • def __str__(self):
  • Any statement with import * in it

Change Log

1.0.0 (2013-08-27)

  • Handle ImproperlyConfigured exception raised by django-discover-runner
  • The runner is now successfully used in several projects so it's moving to 1.0.

0.7.2 (2013-06-19)

  • Require django-discover-runner 1.0 which now backports Django 1.6's implementation of DiscoverRunner.

0.7.1 (2013-06-18)

  • Only install django-discover-runner if the version of Django installed is lower than 1.6

0.7.0 (2013-06-05)

0.6.2 (2013-03-13)

  • Change the default of COVERAGE_OMIT_MODULES back to ['*test*']

0.6.1 (2013-03-06)

  • Include South's test database patching

0.6.0 (2013-02-05)

  • Python 3 support
  • Test suite for app discovery methods
  • --no-coverage option

django-discoverage's People

Contributors

13rac1 avatar ryankask avatar thedrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

thedrow noxan

django-discoverage's Issues

Avoid def lines in the miss statements

Regarding of coverage FAQ

Q: Why do the bodies of functions (or classes) show as executed, but the def lines do not?

This happens because coverage is started after the functions are defined. The definition lines are executed without coverage measurement, then coverage is started, then the function is called. This means the body is measured, but the definition of the function itself is not.

To fix this, start coverage earlier. If you use the command line to run your program with coverage, then your entire program will be monitored. If you are using the API, you need to call coverage.start() before importing the modules that define your functions.

I have not enough experience building unittest suites and discover-runner, I guess that build_suite do the imports of my tests but probably I'm wrong.

So, I tried:

def run_tests(self, test_labels, extra_tests=None, **kwargs):
    cov = coverage.coverage(omit=COVERAGE_OMIT_MODULES)
    cov.start()
    if self.no_coverage:
        # ....

but it doesn't work

What it works is start the coverage at module level

coverage.start()
class DiscoverageRunner(DiscoverRunner):

but I don't think is a good solution

For the purpose of this issue, I show my django_project/tests structure (only what is relevant)

# All folders inside project as python packages (Avoiding print *inits*)
project/
  manage.py
  libs/
    app/
      models.py
  app2/
    models.py
  tests/
    app/test_*.py
    app2/test_*.py

and unittest settings

...
INSTALLED_APPS = ('libs.app', 'app2', 'discoverage')
TEST_RUNNER = 'discoverage.DiscoverageRunner'
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.