feat: dependency graph visualization (Mermaid output)#4948
Conversation
Add the ability to export test dependency graphs as Mermaid (.mmd) files for visualization. When --export-dependency-graph is passed, a .mmd file is generated after test execution showing DependsOn relationships as directed arrows with color-coded nodes (green=passed, red=failed, yellow=skipped, gray=not run). Closes #4889
There was a problem hiding this comment.
Code Review
Overall, this is a clean and well-structured implementation. The Mermaid export logic is clear, edge cases (no dependencies, no tests) are handled, and the opt-in CLI flag design is the right approach. Two issues were found.
Issue 1 — Unnecessary allocation: array passed as List to a method that accepts IReadOnlyList
In ExportDependencyGraphIfRequestedAsync, allTests is AbstractExecutableTest[] (arrays implement IReadOnlyList<T> in .NET), so creating a new List<AbstractExecutableTest>(allTests) just to pass it to GenerateMermaidDiagram allocates an entire new collection unnecessarily.
TUnit/TUnit.Engine/Framework/TestRequestHandler.cs
Lines 95 to 98 in 02276ee
Fix: pass allTests directly:
var mermaidContent = DependencyGraphExporter.GenerateMermaidDiagram(allTests);Issue 2 — Mermaid label sanitization misses backticks in generic type names
test.Metadata.TestClassType.Name returns the CLR internal name for generic types, e.g. MyTests1forMyTests. Backtick ( ) is a special character in Mermaid (used for markdown-formatted labels) and is not currently escaped by SanitizeMermaidLabel. This produces malformed or visually broken node labels for any test class that uses generics.
Note: the rest of the TUnit codebase already handles this — TestIdentifierService, MetadataFilterMatcher, and ReflectionExtensions.GetFormattedName all strip the ``N` arity suffix before display.
TUnit/TUnit.Engine/Services/DependencyGraphExporter.cs
Lines 34 to 38 in 02276ee
Fix: strip the arity suffix from the class name (consistent with what the rest of TUnit does) and escape backticks in SanitizeMermaidLabel:
// When building the label:
var className = test.Metadata.TestClassType.Name;
// Remove generic arity suffix: 'MyClass`2' -> 'MyClass'
var genericSuffixIndex = className.IndexOf('`');
if (genericSuffixIndex >= 0)
className = className[..genericSuffixIndex];
// In SanitizeMermaidLabel, add:
.Replace("`", "#96;")
Closes #4889. Adds --export-dependency-graph option.