Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python unit test coverage for multiple modules

I searched for a long time and surprisingly found no satisfactory answer.

I have multiple modules/files in my Python project that I wrote unit tests for using unittest. The structure is such that I have production-modules module_A.py and module_B.py in one directory (say myproject/production) and corresponding test-files test_module_A.py and test_module_B.py in a sibling directory (say myproject/tests).

Now I have coverage.py installed and want to run all the tests associated with the project (i.e. all .py-files with the prefix test_ from the tests directory) and receive a coverage report showing the coverage for all the production-modules (module_A.py and module_B.py).

I figured out that I can do this by running the following commands from the myproject/tests directory:

  • coverage erase
  • coverage run -a --source myproject.production test_module_A.py
  • coverage run -a --source myproject.production test_module_B.py
  • coverage report

This gives me that nice table with all my production modules listed and their coverage results. So far so good.

But can I do this with just one command? Assuming I have not 2 but 20 or 200 tests that I want to include in one report, doing this "by hand" seems ridiculous.

There must be a way to automate this, but I can't seem to find it. Sure a shell-script might do it, but that is rather clumsy. I am thinking of something akin to unittest discover, but for coverage.py this doesn't seem to work.

Or could I accomplish this using the coverage-API somehow? So far I had no luck trying.

.

SOLUTION: (credit to Mr. Ned Batchelder)

From myproject/tests directory run:

coverage run --source myproject.production -m unittest discover && coverage report

One line, doing exactly what was needed.

like image 598
JohnGalt Avatar asked Nov 26 '17 14:11

JohnGalt


1 Answers

This should do it:

coverage.py run -m unittest discover
like image 176
Ned Batchelder Avatar answered Oct 11 '22 05:10

Ned Batchelder