OLD | NEW |
1 """XML reporting for coverage.py""" | 1 """XML reporting for coverage.py""" |
2 | 2 |
3 import os, sys, time | 3 import os, sys, time |
4 import xml.dom.minidom | 4 import xml.dom.minidom |
5 | 5 |
6 from coverage import __url__, __version__ | 6 from coverage import __url__, __version__ |
7 from coverage.backward import sorted, rpartition # pylint: disable=W0622 | 7 from coverage.backward import sorted, rpartition # pylint: disable=W0622 |
8 from coverage.report import Reporter | 8 from coverage.report import Reporter |
9 | 9 |
10 def rate(hit, num): | 10 def rate(hit, num): |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 bnum_tot += bnum | 78 bnum_tot += bnum |
79 bhits_tot += bhits | 79 bhits_tot += bhits |
80 | 80 |
81 xcoverage.setAttribute("line-rate", rate(lhits_tot, lnum_tot)) | 81 xcoverage.setAttribute("line-rate", rate(lhits_tot, lnum_tot)) |
82 xcoverage.setAttribute("branch-rate", rate(bhits_tot, bnum_tot)) | 82 xcoverage.setAttribute("branch-rate", rate(bhits_tot, bnum_tot)) |
83 | 83 |
84 # Use the DOM to write the output file. | 84 # Use the DOM to write the output file. |
85 outfile.write(self.xml_out.toprettyxml()) | 85 outfile.write(self.xml_out.toprettyxml()) |
86 | 86 |
87 # Return the total percentage. | 87 # Return the total percentage. |
88 return 100.0 * (lhits_tot + bhits_tot) / (lnum_tot + bnum_tot) | 88 denom = lnum_tot + bnum_tot |
| 89 if denom == 0: |
| 90 pct = 0.0 |
| 91 else: |
| 92 pct = 100.0 * (lhits_tot + bhits_tot) / denom |
| 93 return pct |
89 | 94 |
90 def xml_file(self, cu, analysis): | 95 def xml_file(self, cu, analysis): |
91 """Add to the XML report for a single file.""" | 96 """Add to the XML report for a single file.""" |
92 | 97 |
93 # Create the 'lines' and 'package' XML elements, which | 98 # Create the 'lines' and 'package' XML elements, which |
94 # are populated later. Note that a package == a directory. | 99 # are populated later. Note that a package == a directory. |
95 package_name = rpartition(cu.name, ".")[0] | 100 package_name = rpartition(cu.name, ".")[0] |
96 className = cu.name | 101 className = cu.name |
97 | 102 |
98 package = self.packages.setdefault(package_name, [{}, 0, 0, 0, 0]) | 103 package = self.packages.setdefault(package_name, [{}, 0, 0, 0, 0]) |
99 | 104 |
100 xclass = self.xml_out.createElement("class") | 105 xclass = self.xml_out.createElement("class") |
101 | 106 |
102 xclass.appendChild(self.xml_out.createElement("methods")) | 107 xclass.appendChild(self.xml_out.createElement("methods")) |
103 | 108 |
104 xlines = self.xml_out.createElement("lines") | 109 xlines = self.xml_out.createElement("lines") |
105 xclass.appendChild(xlines) | 110 xclass.appendChild(xlines) |
106 | 111 |
107 xclass.setAttribute("name", className) | 112 xclass.setAttribute("name", className) |
108 filename = cu.file_locator.relative_filename(cu.filename) | 113 filename = cu.file_locator.relative_filename(cu.filename) |
109 xclass.setAttribute("filename", filename.replace("\\", "/")) | 114 xclass.setAttribute("filename", filename.replace("\\", "/")) |
110 xclass.setAttribute("complexity", "0") | 115 xclass.setAttribute("complexity", "0") |
111 | 116 |
112 branch_stats = analysis.branch_stats() | 117 branch_stats = analysis.branch_stats() |
113 | 118 |
114 # For each statement, create an XML 'line' element. | 119 # For each statement, create an XML 'line' element. |
115 for line in analysis.statements: | 120 for line in sorted(analysis.statements): |
116 xline = self.xml_out.createElement("line") | 121 xline = self.xml_out.createElement("line") |
117 xline.setAttribute("number", str(line)) | 122 xline.setAttribute("number", str(line)) |
118 | 123 |
119 # Q: can we get info about the number of times a statement is | 124 # Q: can we get info about the number of times a statement is |
120 # executed? If so, that should be recorded here. | 125 # executed? If so, that should be recorded here. |
121 xline.setAttribute("hits", str(int(line not in analysis.missing))) | 126 xline.setAttribute("hits", str(int(line not in analysis.missing))) |
122 | 127 |
123 if self.arcs: | 128 if self.arcs: |
124 if line in branch_stats: | 129 if line in branch_stats: |
125 total, taken = branch_stats[line] | 130 total, taken = branch_stats[line] |
(...skipping 15 matching lines...) Expand all Loading... |
141 class_br_hits = 0.0 | 146 class_br_hits = 0.0 |
142 | 147 |
143 # Finalize the statistics that are collected in the XML DOM. | 148 # Finalize the statistics that are collected in the XML DOM. |
144 xclass.setAttribute("line-rate", rate(class_hits, class_lines)) | 149 xclass.setAttribute("line-rate", rate(class_hits, class_lines)) |
145 xclass.setAttribute("branch-rate", rate(class_br_hits, class_branches)) | 150 xclass.setAttribute("branch-rate", rate(class_br_hits, class_branches)) |
146 package[0][className] = xclass | 151 package[0][className] = xclass |
147 package[1] += class_hits | 152 package[1] += class_hits |
148 package[2] += class_lines | 153 package[2] += class_lines |
149 package[3] += class_br_hits | 154 package[3] += class_br_hits |
150 package[4] += class_branches | 155 package[4] += class_branches |
OLD | NEW |