Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions pycobertura/cobertura1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<coverage line-rate="0.75" branch-rate="0.60" lines-covered="750" lines-valid="1000" branches-covered="60" branches-valid="100">
<packages>
<package name="com.example.package1">
<classes>
<class name="ExampleClass1">
<methods>
<method name="method1">
<lines>
<line number="20" hits="8"/>
<line number="25" hits="12"/>
</lines>
</method>
</methods>
</class>
<class name="ExampleClass2">
<methods>
<method name="method2">
<lines>
<line number="10" hits="5"/>
<line number="15" hits="10"/>
</lines>
</method>
</methods>
</class>
</classes>
</package>
</packages>
</coverage>
29 changes: 29 additions & 0 deletions pycobertura/cobertura2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<coverage line-rate="0.85" branch-rate="0.70" lines-covered="850" lines-valid="1000" branches-covered="70" branches-valid="100">
<packages>
<package name="com.example.package1">
<classes>
<class name="ExampleClass2">
<methods>
<method name="method2">
<lines>
<line number="10" hits="3"/>
<line number="15" hits="8"/>
</lines>
</method>
</methods>
</class>
<class name="ExampleClass3">
<methods>
<method name="method3">
<lines>
<line number="30" hits="6"/>
<line number="35" hits="10"/>
</lines>
</method>
</methods>
</class>
</classes>
</package>
</packages>
</coverage>
59 changes: 59 additions & 0 deletions pycobertura/merge_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import xml.etree.ElementTree as ET
from collections import defaultdict


def merge_coverage_data(files):
merged_data = defaultdict(
lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
)

for file in files:
tree = ET.parse(file)
root = tree.getroot()

for package in root.findall("./packages/package"):
package_name = package.attrib["name"]
for class_ in package.findall("classes/class"):
class_name = class_.attrib["name"]
for method in class_.findall("methods/method"):
method_name = method.attrib["name"]
for line in method.findall("lines/line"):
line_number = line.attrib["number"]
hits = int(line.attrib["hits"])
merged_data[package_name][class_name][method_name][
line_number
] += hits

return merged_data


def generate_merged_xml(merged_data):
root = ET.Element("coverage")

for package_name, package_data in merged_data.items():
package_elem = ET.SubElement(root, "package", name=package_name)
for class_name, class_data in package_data.items():
class_elem = ET.SubElement(package_elem, "class", name=class_name)
for method_name, method_data in class_data.items():
method_elem = ET.SubElement(class_elem, "method", name=method_name)
lines_elem = ET.SubElement(method_elem, "lines")
for line_number, hits in method_data.items():
ET.SubElement(
lines_elem, "line", number=line_number, hits=str(hits)
)

return ET.ElementTree(root)


def main():
files = ["cobertura1.xml", "cobertura2.xml"] # List of Cobertura XML files to merge
merged_data = merge_coverage_data(files)

merged_xml_tree = generate_merged_xml(merged_data)
merged_xml_tree.write(
"merged_cobertura.xml", encoding="utf-8", xml_declaration=True
)


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions pycobertura/merged_cobertura.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version='1.0' encoding='utf-8'?>
<coverage><package name="com.example.package1"><class name="ExampleClass1"><method name="method1"><lines><line number="20" hits="8" /><line number="25" hits="12" /></lines></method></class><class name="ExampleClass2"><method name="method2"><lines><line number="10" hits="8" /><line number="15" hits="18" /></lines></method></class><class name="ExampleClass3"><method name="method3"><lines><line number="30" hits="6" /><line number="35" hits="10" /></lines></method></class></package></coverage>