""" Reads pytest's XML output, and produces a report of the test run(s). """ import dataclasses import functools import itertools import re import sys import textwrap from typing import Optional, Set import xml.etree.ElementTree as ET def visit_bottomup(f, d): """Visits and rewrites a nested-dict ``d`` from the bottom to the top, using the ``f`` predicate.""" if isinstance(d, dict): return f({k: visit_bottomup(f, v) for (k, v) in d.items()}) else: return f(d) @dataclasses.dataclass class CaseResult: success: bool skipped: bool type: Optional[str] = None message: Optional[str] = None @dataclasses.dataclass class CompactedResult: success: bool count: int nb_skipped: int messages: Set[str] def partial_compaction(d): # Group all the perfect successes together, but keep those with skipped # tests separate compacted_d = {} successes = [] for k, v in d.items(): if isinstance(v, CompactedResult) and v.success and v.nb_skipped == 0: successes.append((k, v)) else: compacted_d[k] = v if len(successes) == 0: pass elif len(successes) == 1: ((k, v),) = successes compacted_d[k] = v else: compacted_d["(others)"] = CompactedResult( success=True, count=sum(res.count for (_, res) in successes), nb_skipped=0, messages=set(), ) return compacted_d def compact_results(d): """Rewrite the nested dict ``d`` of CaseResult in a more compact form; by folding successful subtrees.""" if isinstance(d, dict): if set(d) == {None}: return d[None] while len(d) == 1 and all(isinstance(v, dict) for v in d.values()): (key,) = d d = {f"{key}::{k}": v for (k, v) in d[key].items()} if not all(isinstance(v, CompactedResult) for v in d.values()): # Some children are not compactable, so this subtree isn't either return partial_compaction(d) statuses = {v.success for v in d.values()} if len(statuses) == 1: (status,) = statuses return CompactedResult( success=status, count=sum(v.count for v in d.values()), nb_skipped=sum(v.nb_skipped for v in d.values()), messages=set( itertools.chain.from_iterable(v.messages for v in d.values()) ), ) else: return partial_compaction(d) elif isinstance(d, CaseResult): return CompactedResult( success=d.success, count=1, nb_skipped=int(d.skipped), messages={d.message} if d.message else set(), ) else: assert False, repr(d) def format_results(d) -> str: """Using the nested dict ``d`` of CaseResult, formats a string report.""" if isinstance(d, dict): items = [f"
  • {k}: {v}
  • " for (k, v) in d.items()] items_str = textwrap.indent("\n".join(items), prefix=" ") return f"\n" elif isinstance(d, CompactedResult): if d.success: if d.nb_skipped: return f"✔️ {d.count} successful ({d.nb_skipped} skipped)" else: return f"✔️ {d.count} successful" else: assert d.nb_skipped == 0 reason = "".join(f"
  • {msg}
  • " for msg in d.messages) return f"❌ {d.count} failed:\n" else: assert False, d def main(filenames): print("") if __name__ == "__main__": (_, *filenames) = sys.argv exit(main(filenames))