83

I am trying to find the coverage using the coverage module for a django project but gets

Coverage.py warning: No data was collected. (no-data-collected)

My project folder has src and tests folders.

When I run

coverage run -m pytest && coverage report

It produces a report with 100% coverage with the list of files inside the tests folder. Whereas when I run

coverage run --source=src -m pytest && coverage report

it says

Coverage.py warning: No data was collected. (no-data-collected)
No data to report.

When I try to give the source=src or include=src in the .coveragerc also the same warning occurs. The tests passes for all the above cases.

I want the coverage of the src folder. Is it because I am missing some path setting?

2
  • 7
    Perhaps you are not running code from the src folder? Add --debug=trace to the coverage run line. It will print information about each file executed, whether it is traced, and if not, why not. Commented Nov 15, 2017 at 0:59
  • 1
    try to replace src with an actual path. It should point to a folder and not a file Commented Jun 20, 2018 at 17:02

15 Answers 15

46

coverage (used by pytest-cov) needs the tests folder to contain an __init__.py before it will collect any data.

I added __init__.py to the tests folder and then coverage collected the data as expected.

Refer to http://thomas-cokelaer.info/blog/2017/01/pytest-cov-collects-no-data-on-travis/

Sign up to request clarification or add additional context in comments.

2 Comments

Judging by the upvotes this seems to be a solution for some people, but in my case pytest-cov works just fine with no __init__.py files in my tests folder.
This depends on your package layout. Common practice is to keep tests outside of application code, and in this case you don't want __init__.py files in your test directories. If you are using the same name for test modules or have "inline" tests, then you would want __init__.py files in your test directories (See pytest best practices).
24

I had the same issue and the problem was with the path I was running the tests.

What is working now:

Structure

~/Projects/ProjectName
├── manage.py
├── tests
├── src
│   ├── app_one
├── .coveragerc

Command:

~/Projects/ProjectName$ coverage run manage.py test

and my .coveragerc:

[run]
include = */src/*
omit = *migrations*, *tests*
plugins = django_coverage_plugin

5 Comments

where is .coveragerc file?
in the ProjectName folder...will update the structure above
and where do you run pytest now exactly?
What is manage.py?
Manage.py in Django is a command-line utility that works similar to the django-admin command
12

The problem is that you're not specifying which dir to get coverage from.

You can specify that in the .coveragerc file or on the command line:

pytest tests -v --cov-report term --cov-report html:htmlcov --cov-report xml --cov-fail-under=90 --cov=<the-dir-to-colect-coverage-from>

If you desire you can only execute pytest tests and add pytest args on pytest.ini at your project root:

[pytest]
addopts = -v --cov-report term --cov-report html:htmlcov --cov-report xml --cov-fail-under=<coverage-percentage-desired> --cov=<the-dir-to-colect-coverage-from>

Bonus:

If you want to omit files from the coverage you can add a .coveragerc file on your project root:

[run]
omit =
    # omit everything in the folder
    proj-ab/api/confs/
    # omit file
    proj-ab/models/file-not-covered.py

Requirements: On these examples I'm using requirements: pytest==4.6.2 and pytest-cov==2.7.1

2 Comments

I find this comment useful on my end, as I am searching for ways to resolve my pytest-cov usage on my unit tests. Thanks for this!
Can you clarify "<the-dir-to-colect-coverage-from>"? Is it the folder that contains the sources? The test-cases? The project root? Or some other folder that contains a special file? I tried several combinations and none worked. I must be missing something.
11

I had the same issue because I ran pip install .. Because the package name and the code directory had the same name and are in the current directory, coverage probably picked up the directory, while the code that was run was from site-package (or visa versa). pip install -e . made sure there was no confusion.

3 Comments

I don't have exactly the same setup, but found that "pip install -e ." was necessary to get coverage to work again. We usually don't install with "-e" in our Ci/CD pipelines so this is a pain.
I had this problem for some reason when I went back to an old project. Not sure what had happened, but running pip install -e fixed it.
I don't know if using pip install -e . is the solution to the OP's question. However, this solved the issue that I was encountering with regards to the error. This answer should at least be higher rated. This is also the most straightforward answer because it involves zero configuration changes and no restructuring of the project and no additional __init__.py files etc as mentioned in other answers.
7

I had the same issue and the above answers did not fully solve it. It turns out you need to have __init__.py was in every subdirectory that has a test.

Comments

3

if you need to use 'source' in your .coveragerc, you can write as below

[run]
source = src
omit = *migrations*, *tests*
plugins = django_coverage_plugin

Comments

2

I encountered this error with tox:

Coverage.py warning: No data was collected. (no-data-collected)

My configuration performs an install of the module and tests that rather than the source code. However, test discovery was finding a module that I had named test_*.py in my app package, causing PYTHONPATH confusion and resulting in failure to collect coverage details. Renaming the module to not start with test_ resolved the issue.

1 Comment

I had to unset my source setting under [tool.coverage.run] in pyproject.toml. Trying to set a bunch of explicit settings isn't always helpful, it seems...
2

Check your setup.cfg or other ways to implicitely pass flags to pytest

coverage run -m pytest tests

won't work if pytest receives --cov-* flags which basically tell it to generate report itself. Data will be intercepted and coverage will be left with nothing.

We've got this error when we changed tooling and CI/CD scripts. So it might be worth checking if you've recently done the same.

Comments

1

The solution that worked for me: remove "execute" permission from all the *.py files in the scope of the run.

Comments

1

This could also happen when your files are not named correctly. So to recap, make sure that:

  • __init__.py is present in every folder that you have a test in.

  • Your .py test files need to start with test_*.py

  • Your test classes need to start with Test / inherit the unittest Testcase:

    class TestCarController(unittest.TestCase):

Then run this command where -s is your source folder

coverage run -m unittest discover -s tests

With the following commands you can visualize the results in the terminal or html format

coverage report
coverage html

Finally, in order to skip empty files, such as empty __init__.py files, add a .coveragerc file in your root dir.

[run]
source = .

[report]
omit =
    tests/*
skip_empty = True

Comments

0

I already had __init__.py where necessary .

I am not sure why it worked but i simply did:

coverage run --omit='*/venv/*' manage.py test

and then:

coverage html

again and I got my intended result

Comments

0

I experienced this error when using a standard package layout with tox. Turns out there is a tox bug, which necessitates the tox.ini testenv config usedevelop = true.

Working example

layout

.
├── mypackage
│   ├── __init__.py
│   └── module.py
├── tests
│   └── test_module.py
├── pyproject.toml
├── README.md
├── pytest.ini
├── .coveragerc
└── tox.ini

tox.ini

[tox]
verbose = true
min_version = 4.0.0
envlist = py38
isolated_build = true
skip_missing_interpreters = true

[testenv:py38]
extras = dev
usedevelop = true
commands =
  pytest -vvv {posargs}

pytest.ini

[pytest]
testpaths =
    tests
addopts =
    --cov=mypackage
    --cov-report=xml
    --log-cli-level=ERROR
filterwarnings =
    ignore::DeprecationWarning
    ignore::PendingDeprecationWarning

.coveragerc

[run]
source = mypackage
omit =
    venv/*

[report]
exclude_lines =
    pragma: no cover
    def __repr__
    raise NotImplementedError
    if __name__ == .__main__.:

Comments

0

In my situation, the cause of this issue turned out to be surprisingly straightforward: I had inadvertently created an empty folder named "my_module." Consequently, when running pytest, even though the test was successful, pytest-cov attempted to compare the coverage result with that empty folder.

Comments

0

I did:

poetry config --list
poetry run coverage run 

And it fixed the "No Data was collected" warning. [Just adding the poetry config --list line before actually running coverage].

Comments

0

In my case, I installed the package that I'm trying to install with pip install . . It turns out I have to make it editable using pip install -e . so that the package that is run is in the src not in the pip's directory

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.