Python > Testing in Python > Test Coverage > Using `coverage.py`
Measuring Test Coverage with `coverage.py`
This snippet demonstrates how to use `coverage.py` to measure the percentage of your code that is covered by your tests. Understanding test coverage helps you identify areas of your code that are not being adequately tested, allowing you to improve the reliability and maintainability of your software.
Introduction to Test Coverage
Test coverage is a metric that quantifies how much of your codebase is exercised by your tests. It's a valuable tool for identifying gaps in your testing strategy and ensuring that critical parts of your application are thoroughly tested. `coverage.py` is a Python library that provides a straightforward way to measure test coverage. It analyzes your code and determines which lines were executed during your test runs.
Installing `coverage.py`
Before you can use `coverage.py`, you need to install it. You can install it using pip:
pip install coverage
Example Code to Test
Let's consider a simple Python module with a function that adds two numbers:
# my_module.py
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
Writing a Test Case
Now, let's create a test case for the `add` function:
# test_my_module.py
import unittest
from my_module import add
class TestAdd(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(2, 3), 5)
if __name__ == '__main__':
unittest.main()
Running Tests with Coverage
To run the tests with coverage and generate a report, use the following commands:
# Run coverage
coverage run test_my_module.py
# Generate a report
coverage report
# Generate an HTML report (optional)
coverage html
Interpreting the Coverage Report
The `coverage report` command will output a table showing the coverage for each file: Example output: This report shows that `my_module.py` has 50% coverage, meaning that only half of the lines in the file were executed during the test run. Specifically, `subtract` and `multiply` were not tested.
Name Stmts Miss Cover
------------------------------------
my_module.py 4 2 50%
test_my_module.py 6 0 100%
------------------------------------
TOTAL 10 2 80%
Creating HTML Coverage Report
The `coverage html` command will generate an HTML report in the `htmlcov` directory. This report provides a more detailed view of the coverage, highlighting which lines were executed and which were not. Open the `index.html` file in your browser to view the report.
Improving Test Coverage
Based on the coverage report, we can see that the `subtract` function is not covered by any tests. To improve the coverage, we need to add a test case for this function:
# test_my_module.py
import unittest
from my_module import add, subtract, multiply
class TestAdd(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(2, 3), 5)
class TestSubtract(unittest.TestCase):
def test_subtract_positive_numbers(self):
self.assertEqual(subtract(5, 2), 3)
class TestMultiply(unittest.TestCase):
def test_multiply_positive_numbers(self):
self.assertEqual(multiply(5, 2), 10)
if __name__ == '__main__':
unittest.main()
Rerun Coverage
After adding the new test case, rerun the coverage analysis. You should now see 100% coverage for `my_module.py`.
# Rerun coverage
coverage run test_my_module.py
# Generate a report
coverage report
Real-Life Use Case
In a large project, test coverage can help you identify untested or poorly tested modules. This allows you to focus your testing efforts on the most critical and vulnerable parts of your application. For example, if you're refactoring a complex piece of code, you can use coverage to ensure that your changes haven't inadvertently broken existing functionality.
Best Practices
Interview Tip
Be prepared to discuss your experience with test coverage and how you've used it to improve the quality of your code. Explain how you interpret coverage reports and how you use them to identify areas for improvement. Mention `coverage.py` as a tool you're familiar with.
When to use them
Use test coverage during all stages of development, particularly during refactoring, bug fixing, and feature implementation. Make it a standard part of your continuous integration/continuous deployment (CI/CD) pipeline to ensure that code changes don't decrease coverage unexpectedly.
Memory footprint
`coverage.py` itself has a relatively small memory footprint. The main memory usage comes from running your tests. The generated coverage data is typically small unless you are dealing with an extremely large codebase. In general, memory consumption is not a significant concern when using `coverage.py`.
Alternatives
While `coverage.py` is a popular choice, other tools exist:
Pros
Cons
FAQ
-
What does 'Stmt' mean in the coverage report?
'Stmt' stands for 'statements'. It represents the number of executable statements in the file. -
What does 'Miss' mean in the coverage report?
'Miss' represents the number of statements that were not executed during the test run. -
How can I exclude certain files or directories from coverage analysis?
You can exclude files or directories by creating a `.coveragerc` file in your project root. Use the `exclude` option in the `[run]` section. For example: [run] exclude = migrations/ __init__.py -
How to configure `.coveragerc` file?
The `.coveragerc` file allows you to customize the behavior of `coverage.py`. You can specify which files to include or exclude from coverage analysis, configure the reporting format, and set various other options. Refer to the `coverage.py` documentation for a complete list of configuration options. -
Can I use `coverage.py` with pytest?
Yes, you can use `coverage.py` with pytest. The easiest way is to install the `pytest-cov` plugin, which integrates seamlessly with pytest. You can then run your tests with coverage using the `pytest --cov` command.