-
Notifications
You must be signed in to change notification settings - Fork 1
Component Diagrams
TestTrackingDiagrams can aggregate all tracked interactions across your entire test suite to auto-generate a C4-style component diagram. This diagram shows every discovered participant (services, event brokers, databases) and their relationships — giving you a high-level architecture overview derived directly from real test traffic.
This feature is enabled by default (GenerateComponentDiagram = true).
- Quick Start
- How It Works
- Configuration
- Output Files
- Participant Classification
- Relationship Labels
- Customisation
- Example Output
- Integration with PlantUML IKVM
- Performance
- Limitations & Known Behaviours
- API Reference
Add GenerateComponentDiagram = true to your ReportConfigurationOptions (this is the default):
var options = new ReportConfigurationOptions
{
GenerateComponentDiagram = true // already the default
};That's it. When your test run completes and reports are generated, a ComponentDiagram.puml and ComponentDiagram.html file will appear in the Reports/ directory alongside your existing report files.
RequestResponseLogger.RequestAndResponseLogs (all tests, already in memory)
│
▼
ComponentDiagramGenerator.ExtractRelationships()
│ Filters: ignores responses, override markers, action markers, TrackingIgnore
│ Groups by: (CallerName, ServiceName, Protocol)
│ Counts: total calls, distinct test IDs, distinct HTTP methods
▼
ComponentDiagramGenerator.GeneratePlantUml()
│ Classifies participants as Person() or System()
│ Generates C4 Component PlantUML syntax
▼
ComponentDiagramReportGenerator
│ Writes ComponentDiagram.puml (raw PlantUML)
│ Writes ComponentDiagram.html (HTML wrapper)
▼
Reports/ directory
-
Extract — All
RequestResponseLogentries accumulated during the test run are filtered to only include meaningful request logs (excluding responses, override markers, action start markers, and ignored logs). They are then grouped by the unique combination of(CallerName, ServiceName, Protocol)to discover relationships. -
Aggregate — For each relationship, the generator counts total calls, distinct test IDs (how many tests exercised this path), and the distinct HTTP methods or event types used.
-
Generate — The aggregated relationships are converted into PlantUML C4 Component diagram syntax. Participants are classified as
Person()(pure callers, typically your test client) orSystem()(everything else). -
Write — The PlantUML source is written to a
.pumlfile and wrapped in an HTML page for easy viewing.
GenerateComponentDiagram defaults to true. To disable:
var options = new ReportConfigurationOptions
{
GenerateComponentDiagram = false // opt out
};To customise the diagram:
var options = new ReportConfigurationOptions
{
ComponentDiagramOptions = new ComponentDiagramOptions
{
Title = "My Service Architecture"
}
};When GenerateComponentDiagram is false, no component diagram files are generated and there is zero overhead.
| Property | Type | Default | Description |
|---|---|---|---|
FileName |
string |
"ComponentDiagram" |
Base filename for the generated .puml and .html files |
EmbedInFeaturesReport |
bool |
true |
Reserved for future use — will embed the diagram in the FeaturesReport.html |
Title |
string |
"Component Diagram" |
The title displayed in the PlantUML diagram and HTML page |
PlantUmlTheme |
string? |
null |
Optional PlantUML theme name (e.g. "cerulean", "superhero") |
ParticipantFilter |
Func<string, bool>? |
null |
Predicate to include/exclude participants by name |
RelationshipLabelFormatter |
Func<ComponentRelationship, string>? |
null |
Custom function to format relationship labels |
ShowRelationshipFlows |
bool |
true |
Adds a clickable relationship list below the component diagram. Each relationship opens a popup showing the aggregated internal flow (OTel spans) for that caller→service path. Requires InternalFlowTracking = true. |
RelationshipFlowStyle |
InternalFlowDiagramStyle |
ActivityDiagram |
Visual style for relationship flow popups. ActivityDiagram shows a PlantUML diagram. CallTree shows an HTML nested list. |
ShowSystemFlameChart |
bool |
true |
Adds a system-level flow section below the component diagram showing all test spans in a sequential flame chart with a Gantt toggle. |
When enabled, two files are generated in the Reports/ directory:
| File | Description |
|---|---|
ComponentDiagram.puml |
Raw PlantUML C4 source. This is a plain text file that can be version-controlled and diffed to detect architectural changes between commits. |
ComponentDiagram.html |
A standalone HTML page containing the PlantUML source in a collapsible <details> element. Can be opened directly in a browser. |
The filenames can be customised via ComponentDiagramOptions.FileName.
Participants are automatically classified based on their role in the tracked interactions:
| Classification | PlantUML element | Rule |
|---|---|---|
| Person | Person(alias, "Name") |
The participant only appears as a CallerName and never as a ServiceName in any tracked log. This is typically your test client / SUT caller. |
| System | System(alias, "Name") |
The participant appears as a ServiceName in at least one tracked log. This includes your SUT, its downstream dependencies, event brokers, and databases. |
A service that both receives calls and makes downstream calls (e.g. your SUT calling a payment service) is rendered as a System because it appears as a ServiceName.
By default, each relationship label contains:
<Protocol>: <Methods> — <CallCount> calls across <TestCount> tests
Examples:
HTTP: GET, POST — 14 calls across 8 testsPublish: Publish — 3 calls across 2 testsCosmosDB: Query, Upsert — 5 calls across 3 tests
The protocol is determined automatically:
-
HTTP — For standard HTTP requests (
MetaType == Default). The distinct HTTP method names (GET, POST, PUT, etc.) are listed. -
Event/Custom — For non-HTTP interactions (
MetaType == Event), the protocol is the string value of theMethodproperty onRequestResponseLog(e.g."Publish","CosmosDB","SQL").
var options = new ComponentDiagramOptions
{
Title = "Order Service Architecture"
};Apply any built-in PlantUML theme:
var options = new ComponentDiagramOptions
{
PlantUmlTheme = "cerulean"
};This inserts !theme cerulean into the generated PlantUML.
Exclude specific participants from the component diagram:
var options = new ComponentDiagramOptions
{
// Exclude internal helper services and health check endpoints
ParticipantFilter = name => name != "InternalHelper" && name != "HealthCheck"
};The filter is a Func<string, bool> that receives the participant name. Return true to include, false to exclude. When a participant is excluded, all relationships involving that participant (as either caller or service) are removed.
Override the default label format with a custom formatter:
var options = new ComponentDiagramOptions
{
RelationshipLabelFormatter = rel =>
$"{rel.Protocol} ({rel.CallCount} calls)"
};The ComponentRelationship record passed to the formatter contains:
| Property | Type | Description |
|---|---|---|
Caller |
string |
The calling participant name |
Service |
string |
The receiving participant name |
Protocol |
string |
"HTTP" or the event/custom protocol name |
Methods |
HashSet<string> |
Distinct method names (e.g. GET, POST, Publish) |
CallCount |
int |
Total number of calls across all tests |
TestCount |
int |
Number of distinct tests that exercised this relationship |
Given a test suite that exercises an Order Service with downstream dependencies:
@startuml
!include <C4/C4_Component>
title Order Service Architecture
Person(webApp, "WebApp")
System(orderService, "OrderService")
System(paymentService, "PaymentService")
System(kafka, "Kafka")
System(cosmosDb, "CosmosDB")
Rel(webApp, orderService, "HTTP: GET, POST — 14 calls across 8 tests")
Rel(orderService, paymentService, "HTTP: POST — 6 calls across 4 tests")
Rel(orderService, kafka, "Publish: Publish — 3 calls across 2 tests")
Rel(orderService, cosmosDb, "CosmosDB: Query, Upsert — 5 calls across 3 tests")
@endumlThis diagram is derived entirely from actual test HTTP traffic and event tracking — it cannot drift from reality as long as your tests pass.
When ShowRelationshipFlows is enabled (the default) and InternalFlowTracking is enabled, the component diagram HTML page includes:
- A clickable relationship list — Below the component diagram image, each discovered relationship (e.g. "WebApp → OrderService") is listed as a clickable item.
-
Flow popups — Clicking a relationship opens a modal popup showing:
- An aggregated flow diagram (activity diagram or call tree) combining all spans from all tests that exercised that relationship.
- A summary table showing the top 20 tests sorted by duration, with span count and total duration.
To disable relationship flows:
var options = new ReportConfigurationOptions
{
GenerateComponentDiagram = true,
ComponentDiagramOptions = new ComponentDiagramOptions
{
ShowRelationshipFlows = false
}
};For test suites with many tests (1500+), the summary table shows the top 20 tests by duration with a "and N more tests" indicator at the bottom.
When ShowSystemFlameChart is enabled (the default) and InternalFlowTracking is enabled, the component diagram page includes an inline System Flow section:
- Flame Chart — A sequential test flame chart where each test occupies its own horizontal band with a label divider. Spans are rendered as horizontal bars proportional to their duration within each test's time window.
- Gantt — A PlantUML Gantt chart showing all spans from all tests.
A toggle button lets you switch between the Flame Chart and Gantt views.
Context menu: When relationship flows or system flame charts are present, the context menu is available on all interactive content in the component diagram HTML. Right-click any activity diagram SVG, flame chart, or call tree for copy/save options. See Inline SVG Rendering#context-menu for details.
To disable the system flame chart:
var options = new ReportConfigurationOptions
{
GenerateComponentDiagram = true,
ComponentDiagramOptions = new ComponentDiagramOptions
{
ShowSystemFlameChart = false
}
};The component diagram feature works with the standard PlantUML server rendering. If you're using PlantUML IKVM for local rendering, the .puml file can still be rendered locally using the IKVM renderer, but the component diagram report itself currently outputs raw PlantUML source in the HTML file rather than a rendered image.
Future versions may add support for rendering the component diagram as an image via the local renderer.
The component diagram feature has negligible performance impact:
| Aspect | Impact |
|---|---|
| Data source | Reads the same RequestResponseLogger.RequestAndResponseLogs that are already in memory — no additional data collection |
| Processing | Single O(n) pass over log entries with GroupBy — microseconds for typical test suites (100–10,000 logs) |
| Memory | Aggregated relationships are O(unique participant pairs), typically < 50 entries |
| File I/O | Two small files (.puml + .html) written in parallel with existing report generation |
| When disabled | Zero cost — a single if guard at the entry point |
-
Request-only aggregation — Only request logs are counted. Response logs are excluded to avoid double-counting (a request and its response represent a single interaction).
-
Protocol detection — HTTP interactions (
MetaType == Default) are grouped under the"HTTP"protocol. Event/message interactions (MetaType == Event) use theMethodvalue as the protocol name. If multiple event types share the same method name but different service names, they are tracked as separate relationships. -
Override and action markers —
IsOverrideStart,IsOverrideEnd, andIsActionStartlog entries are excluded from aggregation, consistent with how they're handled in sequence diagrams. -
Static data — The component diagram is generated from
RequestResponseLogger.RequestAndResponseLogs, which is a static concurrent queue. In test runs where the queue is shared across frameworks or assemblies, all interactions are included. -
No rendered image — The current implementation outputs raw PlantUML source. You can paste it into plantuml.com or use a PlantUML VS Code extension to render it visually.
// Extract unique relationships from tracked logs
public static ComponentRelationship[] ExtractRelationships(
IEnumerable<RequestResponseLog> logs,
Func<string, bool>? participantFilter = null);
// Generate C4 PlantUML from relationships
public static string GeneratePlantUml(
ComponentRelationship[] relationships,
ComponentDiagramOptions? options = null);// Generate the .puml and .html report files
public static ComponentDiagramResult GenerateComponentDiagramReport(
IEnumerable<RequestResponseLog> logs,
ComponentDiagramOptions? options = null);public record ComponentDiagramResult(
string PumlFilePath, // Absolute path to the generated .puml file
string HtmlFilePath, // Absolute path to the generated .html file
string PlantUml); // The raw PlantUML stringpublic record ComponentRelationship(
string Caller, // Calling participant name
string Service, // Receiving participant name
string Protocol, // "HTTP" or custom protocol name
HashSet<string> Methods, // Distinct method names
int CallCount, // Total calls across all tests
int TestCount); // Distinct test countpublic record ComponentDiagramOptions
{
public string FileName { get; set; } = "ComponentDiagram";
public bool EmbedInFeaturesReport { get; set; } = true;
public string Title { get; set; } = "Component Diagram";
public string? PlantUmlTheme { get; set; }
public Func<string, bool>? ParticipantFilter { get; set; }
public Func<ComponentRelationship, string>? RelationshipLabelFormatter { get; set; }
public bool ShowRelationshipFlows { get; set; } = true;
public InternalFlowDiagramStyle RelationshipFlowStyle { get; set; } = InternalFlowDiagramStyle.ActivityDiagram;
public bool ShowSystemFlameChart { get; set; } = true;
}public bool GenerateComponentDiagram { get; set; } = true; // Default: true
public ComponentDiagramOptions? ComponentDiagramOptions { get; set; } // Default: nullGetting Started
Common Tasks
Integration Guides
- Integration xUnit3
- Integration xUnit2
- Integration NUnit
- Integration MSTest
- Integration TUnit
- Integration BDDfy xUnit3
- Integration LightBDD xUnit2
- Integration LightBDD xUnit3
- Integration LightBDD TUnit
- Integration ReqNRoll xUnit2
- Integration ReqNRoll xUnit3
- Integration ReqNRoll TUnit
Extensions
- Integration AtlasDataApi Extension
- Integration BigQuery Extension
- Integration Bigtable Extension
- Integration BlobStorage Extension
- Integration ClickHouse Extension
- Integration CloudStorage Extension
- Integration CosmosDB Extension
- Integration Dapper Extension
- Integration DynamoDB Extension
- Integration EF Core Relational Extension
- Integration Elasticsearch Extension
- Integration EventBridge Extension
- Integration EventHubs Extension
- Integration Grpc Extension
- Integration Kafka Extension
- Integration MassTransit Extension
- Integration MongoDB Extension
- Integration MySqlConnector Extension
- Integration Npgsql Extension
- Integration Oracle Extension
- Integration PubSub Extension
- Integration Redis Extension
- Integration S3 Extension
- Integration ServiceBus Extension
- Integration SNS Extension
- Integration Spanner Extension
- Integration SqlClient Extension
- Integration Sqlite Extension
- Integration SQS Extension
- Integration StorageQueues Extension
- Integration OpenTelemetry Extension
- Integration DispatchProxy Extension
- Integration MediatR Extension
- Integration PlantUML IKVM
Configuration
- Tracking Dependencies
- Tracking Custom Dependencies
- HTTP Tracking Setup
- Report Configuration
- Diagram Customisation
- Phase-Aware Tracking
- Content Formatting
- PlantUML Server Configuration
Features
- Generated Reports
- Search Syntax
- Component Diagrams
- PlantUML Browser Rendering
- Inline SVG Rendering
- Internal Flow Tracking
- Tags and Attributes
- Excluding Requests
- Excluded Headers
- Multi-Host Test Architectures
- Event-Driven Architecture Testing
- Service Bus Tracking Patterns
- Background Thread Correlation
- Parallel-Safe Background Correlation
- Event & Message Tracking
- Assertion Tracking
- Step Tracking
- Tabular Attributes
- Large Response and Diagram Handling
- Diagnostics and Debugging
- CI Summary Integration
- CI Artifact Upload
- Merging Parallel Reports
Reference