Test Coverage¶
You can integrate Coverage.py with behave-django to find out the test coverage of your code.
There are two ways to do this. The simple (and obvious one) is via invocation
through the coverage
CLI. Alternatively, you can integrate Coverage in the
environment.py
file of your BDD test setup as shown below.
Prerequisites¶
Obviously, you need to install Coverage to measure code coverage, e.g.
$ pip install coverage[toml]
Invoke via coverage
¶
Instead of using python manage.py
, you simply use
coverage run manage.py
to invoke your BDD tests, e.g.
$ coverage run manage.py behave
Afterwards, you can display a coverage report in your terminal to understand which lines your tests are missing, e.g.
$ coverage report --show-missing
Tip
A Django project setup with coverage configured in pyproject.toml
and
executed by Tox is show-cased in the Painless CI/CD Copier template for
Django.
Integrate via environment.py
¶
In environment.py
, add the code snippet below in the before_all
function
to start measuring test coverage:
import coverage
def before_all(context):
cov = coverage.Coverage()
cov.start()
context.cov = cov
Then write below code to end up measuring test coverage. You can save the coverage result on html format.
def after_all(context):
cov = context.cov
cov.stop()
cov.save()
cov.html_report(directory="./cov")
You can check the test coverage on the web with the following command.
$ python -m http.server --directory ./cov
Warning
Internally, the time before_all
is executed seems to be later than the
time when django loads the modules set in each app.
So sometimes it is necessary to reload django app’s modules for accurate test coverage measurement.
Like this:
import inspect
import importlib
def reload_modules():
import your_app1
import your_app2
for app in [your_app1, your_app2]:
members = inspect.getmembers(app)
modules = map(
lambda keyval: keyval[1],
filter(lambda keyval: inspect.ismodule(keyval[1]), members),
)
for module in modules:
try:
importlib.reload(module)
except:
continue
def before_all(context):
# cov
cov = coverage.Coverage()
cov.start()
context.cov = cov
# modules
reload_modules()