Skip to content

feat(testing): add JUnitFormatter for deterministic XML test reports#1571

Open
murad-1999 wants to merge 1 commit intomofa-org:mainfrom
murad-1999:feature/junit-xml-export
Open

feat(testing): add JUnitFormatter for deterministic XML test reports#1571
murad-1999 wants to merge 1 commit intomofa-org:mainfrom
murad-1999:feature/junit-xml-export

Conversation

@murad-1999
Copy link
Copy Markdown

@murad-1999 murad-1999 commented Apr 3, 2026

📋 Summary

This PR introduces the JUnitFormatter to the mofa-testing crate, enabling the deterministic generation of Ant/Surefire compliant JUnit XML test reports.

🔗 Related Issues

Closes #

Related to #
Issue #1567


🧠 Context

  • Added JUnitFormatter: Implements the ReportFormatter trait to generate <testsuite>, <testcase>, <failure>, and <skipped/> XML tags natively.
  • Zero Bloat: Achieved the implementation entirely through a manual, highly-efficient string builder without adding heavy XML serialization dependencies to Cargo.toml.
  • Security First (XML Escaping): Added a robust escape_xml utility that safely encodes <, >, &, ", and '. It also intercepts and strips invalid raw control characters and handles chaotic inputs (CDATA, emojis, null bytes) to prevent strict XML parsers from crashing.
  • CI Determinism: Ensures flake-free CI by enforcing a strict sequential iteration order and explicitly formatting all floats (durations) to exactly 3 decimal places ({:.3}).
  • Memory Efficiency: Implemented payload truncation on the <failure message="..."> attribute to prevent massive memory allocations and redundant XML bloat when handling massive stack traces.
  • Exports: Exposed the formatter correctly at tests/src/report/mod.rs and tests/src/lib.rs

🛠️ Changes

tests/src/lib.rs (Added public export)
tests/src/report/mod.rs (Added module export)
tests/src/report/format.rs (Core implementation, escape_xml logic, and unit tests)-->


🧪 How you Tested

Added comprehensive, strict string-literal snapshot tests covering:

  • test_all_passing: Validates a clean test run.
  • test_mixed_status: Validates failures and skips mapping to <failure> and <skipped/>.
  • test_case_with_error_payload: Validates basic XML character escaping.
  • test_case_with_metadata: Validates structure when metadata is present.
  • test_chaotic_escaping: Stress tests the escaping utility against null bytes, emojis, and deeply nested quotes.

📸 Screenshots / Logs (if applicable)


⚠️ Breaking Changes

  • No breaking changes
  • Breaking change (describe below)

If breaking:


🧹 Checklist

Code Quality

  • Code follows Rust idioms and project conventions
  • cargo fmt run
  • cargo clippy passes without warnings

Testing

  • Tests added/updated
  • cargo test passes locally without any error

Documentation

  • Public APIs documented
  • README / docs updated (if needed)

PR Hygiene

  • PR is small and focused (one logical change)
  • Branch is up to date with main
  • No unrelated commits
  • [ x] Commit messages explain why, not only what

🚀 Deployment Notes (if applicable)


🧩 Additional Notes for Reviewers

@murad-1999 murad-1999 closed this Apr 3, 2026
@murad-1999 murad-1999 reopened this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant