Skip to content

Commit aabc540

Browse files
christoph-blessingnedbat
authored andcommittedSep 29, 2022
feat: include branches taken and missed in JSON report. #1425
Added more branches to the code whose coverage is checked. Add branch details to json report The json report now includes for each branch which branches have been executed, missed and what the percentage of covered branches was. Add exiting branch arc to json report test Update branch details format Executed and missing branch arcs are stored in the fields named 'executed_branches' and 'missing_branches' respectively. Both fields contain a list of two element lists. The first element represents the source line number and the second one the target line number. Exit branches have their target line number set to 0. Fix linting errors
1 parent a59fc44 commit aabc540

File tree

2 files changed

+83
-45
lines changed

2 files changed

+83
-45
lines changed
 

‎coverage/jsonreport.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,17 @@ def report_one_file(self, coverage_data, analysis):
102102
'covered_branches': nums.n_executed_branches,
103103
'missing_branches': nums.n_missing_branches,
104104
})
105+
reported_file['executed_branches'] = list(
106+
_convert_branch_arcs(analysis.executed_branch_arcs())
107+
)
108+
reported_file['missing_branches'] = list(
109+
_convert_branch_arcs(analysis.missing_branch_arcs())
110+
)
105111
return reported_file
112+
113+
114+
def _convert_branch_arcs(branch_arcs):
115+
"""Convert branch arcs to a list of two-element tuples."""
116+
for source, targets in branch_arcs.items():
117+
for target in targets:
118+
yield source, target if target != -1 else 0

‎tests/test_json.py

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ def _assert_expected_json_report(self, cov, expected_result):
2121
a = {'b': 1}
2222
if a.get('a'):
2323
b = 1
24+
elif a.get('b'):
25+
b = 2
26+
else:
27+
b = 3
28+
if not a:
29+
b = 4
2430
""")
2531
a = self.start_import_stop(cov, "a")
2632
output_path = os.path.join(self.temp_dir, "a.json")
@@ -43,34 +49,44 @@ def test_branch_coverage(self):
4349
},
4450
'files': {
4551
'a.py': {
46-
'executed_lines': [1, 2],
47-
'missing_lines': [3],
52+
'executed_lines': [1, 2, 4, 5, 8],
53+
'missing_lines': [3, 7, 9],
4854
'excluded_lines': [],
55+
'executed_branches': [
56+
[2, 4],
57+
[4, 5],
58+
[8, 0],
59+
],
60+
'missing_branches': [
61+
[2, 3],
62+
[4, 7],
63+
[8, 9],
64+
],
4965
'summary': {
50-
'missing_lines': 1,
51-
'covered_lines': 2,
52-
'num_statements': 3,
53-
'num_branches': 2,
66+
'missing_lines': 3,
67+
'covered_lines': 5,
68+
'num_statements': 8,
69+
'num_branches': 6,
5470
'excluded_lines': 0,
55-
'num_partial_branches': 1,
56-
'covered_branches': 1,
57-
'missing_branches': 1,
58-
'percent_covered': 60.0,
59-
'percent_covered_display': '60',
71+
'num_partial_branches': 3,
72+
'covered_branches': 3,
73+
'missing_branches': 3,
74+
'percent_covered': 57.142857142857146,
75+
'percent_covered_display': '57',
6076
},
6177
},
6278
},
6379
'totals': {
64-
'missing_lines': 1,
65-
'covered_lines': 2,
66-
'num_statements': 3,
67-
'num_branches': 2,
80+
'missing_lines': 3,
81+
'covered_lines': 5,
82+
'num_statements': 8,
83+
'num_branches': 6,
6884
'excluded_lines': 0,
69-
'num_partial_branches': 1,
70-
'percent_covered': 60.0,
71-
'percent_covered_display': '60',
72-
'covered_branches': 1,
73-
'missing_branches': 1,
85+
'num_partial_branches': 3,
86+
'percent_covered': 57.142857142857146,
87+
'percent_covered_display': '57',
88+
'covered_branches': 3,
89+
'missing_branches': 3,
7490
},
7591
}
7692
self._assert_expected_json_report(cov, expected_result)
@@ -85,26 +101,26 @@ def test_simple_line_coverage(self):
85101
},
86102
'files': {
87103
'a.py': {
88-
'executed_lines': [1, 2],
89-
'missing_lines': [3],
104+
'executed_lines': [1, 2, 4, 5, 8],
105+
'missing_lines': [3, 7, 9],
90106
'excluded_lines': [],
91107
'summary': {
92108
'excluded_lines': 0,
93-
'missing_lines': 1,
94-
'covered_lines': 2,
95-
'num_statements': 3,
96-
'percent_covered': 66.66666666666667,
97-
'percent_covered_display': '67',
109+
'missing_lines': 3,
110+
'covered_lines': 5,
111+
'num_statements': 8,
112+
'percent_covered': 62.5,
113+
'percent_covered_display': '62',
98114
},
99115
},
100116
},
101117
'totals': {
102118
'excluded_lines': 0,
103-
'missing_lines': 1,
104-
'covered_lines': 2,
105-
'num_statements': 3,
106-
'percent_covered': 66.66666666666667,
107-
'percent_covered_display': '67',
119+
'missing_lines': 3,
120+
'covered_lines': 5,
121+
'num_statements': 8,
122+
'percent_covered': 62.5,
123+
'percent_covered_display': '62',
108124
},
109125
}
110126
self._assert_expected_json_report(cov, expected_result)
@@ -130,34 +146,43 @@ def run_context_test(self, relative_files):
130146
},
131147
'files': {
132148
'a.py': {
133-
'executed_lines': [1, 2],
134-
'missing_lines': [3],
149+
'executed_lines': [1, 2, 4, 5, 8],
150+
'missing_lines': [3, 7, 9],
135151
'excluded_lines': [],
136152
"contexts": {
137153
"1": [
138154
"cool_test"
139155
],
140156
"2": [
141157
"cool_test"
142-
]
158+
],
159+
"4": [
160+
"cool_test"
161+
],
162+
"5": [
163+
"cool_test"
164+
],
165+
"8": [
166+
"cool_test"
167+
],
143168
},
144169
'summary': {
145170
'excluded_lines': 0,
146-
'missing_lines': 1,
147-
'covered_lines': 2,
148-
'num_statements': 3,
149-
'percent_covered': 66.66666666666667,
150-
'percent_covered_display': '66.67',
171+
'missing_lines': 3,
172+
'covered_lines': 5,
173+
'num_statements': 8,
174+
'percent_covered': 62.5,
175+
'percent_covered_display': '62.50',
151176
},
152177
},
153178
},
154179
'totals': {
155180
'excluded_lines': 0,
156-
'missing_lines': 1,
157-
'covered_lines': 2,
158-
'num_statements': 3,
159-
'percent_covered': 66.66666666666667,
160-
'percent_covered_display': '66.67',
181+
'missing_lines': 3,
182+
'covered_lines': 5,
183+
'num_statements': 8,
184+
'percent_covered': 62.5,
185+
'percent_covered_display': '62.50',
161186
},
162187
}
163188
self._assert_expected_json_report(cov, expected_result)

0 commit comments

Comments
 (0)