diff --git a/src/agentunit/reporting/html.py b/src/agentunit/reporting/html.py new file mode 100644 index 0000000..2bbabba --- /dev/null +++ b/src/agentunit/reporting/html.py @@ -0,0 +1,102 @@ +from __future__ import annotations + +from html import escape +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from agentunit.reporting.results import SuiteResult + + +def render_html_report(result: SuiteResult) -> str: + scenarios = result.scenarios + + total_runs = sum(len(s.runs) for s in scenarios) + failed_runs = sum(1 for s in scenarios for r in s.runs if not r.success) + passed_runs = total_runs - failed_runs + duration = (result.finished_at - result.started_at).total_seconds() + + scenario_rows: list[str] = [] + + for scenario in scenarios: + scenario_rows.append( + f""" + + {escape(scenario.name)} + {scenario.success_rate:.2%} + {len(scenario.runs)} + + """ + ) + + return f""" + + + + AgentUnit Report + + + + + +

AgentUnit HTML Report

+

+ Duration: {duration:.2f}s · Total runs: {total_runs} +

+ +

Summary

+

Passed: {passed_runs} · Failed: {failed_runs}

+ +
+
+ +

Scenarios

+ + + + + + + {"".join(scenario_rows)} +
NameSuccess rateRuns
+ + + +""" diff --git a/src/agentunit/reporting/results.py b/src/agentunit/reporting/results.py index 06f5f06..1228b7b 100644 --- a/src/agentunit/reporting/results.py +++ b/src/agentunit/reporting/results.py @@ -9,6 +9,8 @@ from pathlib import Path from typing import TYPE_CHECKING +from agentunit.reporting.html import render_html_report + if TYPE_CHECKING: from collections.abc import Iterable @@ -128,6 +130,16 @@ def to_junit(self, path: str | Path) -> Path: tree.write(target, encoding="utf-8", xml_declaration=True) return target + def to_html(self, path: str | Path) -> Path: + """ + Export results as a self-contained HTML report. + """ + target = Path(path) + target.parent.mkdir(parents=True, exist_ok=True) + html = render_html_report(self) + target.write_text(html, encoding="utf-8") + return target + def merge_results(results: Iterable[SuiteResult]) -> SuiteResult: results = list(results)