Skip to content

Commit 9682c89

Browse files
committed
merging branches
2 parents 9c8b708 + f7162e7 commit 9682c89

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ htmlcov/
5353
.cache
5454
nosetests.xml
5555
coverage.xml
56+
coverage.json
5657
*.cover
5758
*.py,cover
5859
.hypothesis/

COVERAGE.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,65 @@ python -m coverage erase
3232
(cd examples && python -m coverage run --append --source=pm4py execute_everything.py --pipeline)
3333
python -m coverage report
3434
```
35+
36+
## List the remaining uncovered functions
37+
38+
coverage.py records execution at the statement/line level. To first see which
39+
modules still contain missing statements, read the combined `.coverage` data
40+
produced above with:
41+
42+
```bash
43+
python -m coverage report --show-missing --skip-covered --sort=cover
44+
```
45+
46+
This report lists module paths and missing line numbers, not function names.
47+
With coverage.py 7.15.2, function and method regions are also included in the
48+
JSON report. The completely uncovered functions can therefore be retrieved
49+
from the same combined data as follows:
50+
51+
```bash
52+
python -m coverage json --pretty-print -o coverage.json
53+
python - <<'PY'
54+
import json
55+
56+
with open("coverage.json", encoding="utf-8") as report_file:
57+
report = json.load(report_file)
58+
59+
uncovered = []
60+
for filename, file_data in report["files"].items():
61+
for function_name, function_data in file_data.get("functions", {}).items():
62+
summary = function_data["summary"]
63+
64+
# The empty name represents statements at module scope, not a function.
65+
if (
66+
function_name
67+
and summary["num_statements"] > 0
68+
and summary["covered_lines"] == 0
69+
):
70+
uncovered.append(
71+
(
72+
filename,
73+
function_data["start_line"],
74+
function_name,
75+
function_data["missing_lines"],
76+
)
77+
)
78+
79+
for filename, start_line, function_name, missing_lines in sorted(uncovered):
80+
lines = ",".join(str(line) for line in missing_lines)
81+
print(f"{filename}:{start_line}: {function_name} (missing lines: {lines})")
82+
PY
83+
```
84+
85+
The filter above has a deliberately strict meaning of *uncovered*: the region
86+
has at least one executable statement and none of its statements ran. It
87+
excludes the empty-name region used for module-level statements and functions
88+
with no measurable statements (for example, a body excluded by a coverage
89+
pragma). Class methods are listed with qualified names such as
90+
`ClassName.method_name`.
91+
92+
To also list partially covered functions, replace
93+
`summary["covered_lines"] == 0` with `summary["missing_lines"] > 0`. In that
94+
case, any function with at least one unexecuted statement is included. Both
95+
commands inspect the final combined `.coverage` file, so they should be run
96+
after the test run and the appended example run.

0 commit comments

Comments
 (0)