Diff-Cover
Diff-Cover is a command-line tool that enhances code review by reporting test coverage and linting violations specifically on new or modified lines within a Git diff. It compares an XML coverage report (e.g., Cobertura, Clover, JaCoCo, or LCov format) with the output of `git diff` to highlight lines that lack test coverage or contain quality issues. The library is currently at version 10.2.0 and maintains an active release cadence with frequent updates and dependency bumps.
Warnings
- breaking Version 10.1.0 updated the minimum required Python version to `>=3.10`. Version 10.0.0 explicitly dropped support for Python 3.9 while adding support for Python 3.14. Users on older Python versions (e.g., 3.9 or earlier) must upgrade their Python environment or use an older `diff-cover` version.
- gotcha `diff-cover` relies on source file paths matching exactly between the coverage report and the Git diff. Mismatched relative paths are a common cause of 'No lines with coverage information in this diff.' errors. Version 10.2.0 added support for converting violation paths to relative paths for subfolder support. Version 9.7.2 fixed file name matching on Windows.
- gotcha `diff-cover` may not accurately analyze changes within multi-line statements because coverage reports typically list code statements rather than every changed line. This can lead to lines changed in the diff not being reported in coverage.
- deprecated In version 10.0.0, the `include` and `exclude` arguments were normalized to accept both a string or a list. While this is generally an improvement, older configurations expecting only one type might behave unexpectedly if not reviewed.
- gotcha Older versions of `diff-cover` had compatibility issues with Ruff, particularly when Ruff versions >= 0.12.9 were used, requiring a forced Pylint output format. While fixed in v9.7.0 and v9.7.1, users integrating Ruff should be aware.
Install
-
pip install diff-cover -
pip install diff-cover[flake8,mypy,pylint,ruff]
Quickstart
git init # Create some dummy files and commits for a diff echo "def func1():\n pass" > file1.py git add file1.py git commit -m "Initial commit" echo "def func2():\n return 1 # new line" >> file1.py git add file1.py git commit -m "Add func2" # Run your tests with coverage and generate an XML report # (Requires pytest-cov and pytest to be installed) # For a real project, this would run actual tests pytest --cov=. --cov-report=xml --ignore=file1.py # Now, run diff-cover on the generated coverage.xml against the latest diff # This example might report 'No lines with coverage information in this diff.' # if the dummy coverage report doesn't perfectly align with the diff. # In a real scenario, `pytest --cov` would cover the changed lines. diff-cover coverage.xml