Skip to content

Instantly share code, notes, and snippets.

@cboddy
Created March 12, 2021 20:50
Show Gist options
  • Save cboddy/f29d2a466a209ae6b97710cb9f9e2ac7 to your computer and use it in GitHub Desktop.
Save cboddy/f29d2a466a209ae6b97710cb9f9e2ac7 to your computer and use it in GitHub Desktop.
A CI check to read a Junit test report and raise an error if the time exceeds a threshold.
#!/usr/bin/env python3
import argparse
import collections
import sys
import glob
from typing import *
from xml.dom import minidom
TestCase = collections.namedtuple("TestCase", ["class_name", "test_name", "time"])
def parse(f_path: str) -> List[TestCase]:
"""Parse a Junit XML test-report"""
parsed = minidom.parse(f_path)
elems = parsed.getElementsByTagName("testcase")
return [
TestCase(
class_name=elem.attributes["classname"].value,
test_name=elem.attributes["name"].value,
time=elem.attributes["time"].value,
)
for elem in elems
]
def main():
parser = argparse.ArgumentParser("JUnit test report checker")
parser.add_argument("--path", help="Path to JUnit test-report XML file", required=True)
parser.add_argument(
"--test-time-threshold", help="Minimum test-time-duration (in seconds) to report", required=True
)
args = parser.parse_args()
print(f"Running JUnit report-checker with args {args}")
paths = glob.glob(args.path)
if len(paths) == 0:
print(f"No reports found in {args.path}")
else:
print(f"Checking the following test-report files {paths}")
rc = 0
for path in paths:
try:
test_cases = parse(path)
reportable_cases = [case for case in test_cases if case.time > args.test_time_threshold]
for test_case in reportable_cases:
print(f"{test_case.class_name}.{test_case.test_name} took {test_case.time} seconds")
rc = 1
except:
print(f"Failed to parse {path}: {sys.exc_info()[1]}")
sys.exit(rc)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment