-
Notifications
You must be signed in to change notification settings - Fork 1
Assertion Tracking
Added in v2.28.30
Track.That() captures assertion expressions and renders them as styled inline notes in your sequence diagrams. Passing assertions appear as green notes (✓), and failing assertions appear as red notes (✗) with the failure message.
This makes it immediately visible what was verified at each point in a test flow — directly inside the diagram, without navigating to test code.
using TestTrackingDiagrams.Tracking;
[Fact]
public async Task Creates_order_and_returns_201()
{
var response = await _client.PostAsJsonAsync("/orders", new { Item = "Widget", Qty = 3 });
Track.That(() => response.StatusCode.Should().Be(HttpStatusCode.Created));
var order = await response.Content.ReadFromJsonAsync<Order>();
Track.That(() => order!.Item.Should().Be("Widget"));
Track.That(() => order!.Qty.Should().Be(3));
}This produces three green assertion notes in the sequence diagram:
- ✓ Response status code should be Created
- ✓ Order item should be Widget
- ✓ Order qty should be 3
All methods live in the TestTrackingDiagrams.Tracking namespace on the static Track class.
public static void That(
Action assertion,
[CallerArgumentExpression(nameof(assertion))] string? expression = null)Executes the assertion and logs an inline note. On failure, logs a red note and re-throws the exception.
public static T That<T>(
Func<T> assertion,
[CallerArgumentExpression(nameof(assertion))] string? expression = null)Same as above but returns the value produced by the expression. Useful when you want to capture a result and assert on it in one step:
var count = Track.That(() => items.Should().HaveCount(5).And.Subject.Count);public static async Task ThatAsync(
Func<Task> assertion,
[CallerArgumentExpression(nameof(assertion))] string? expression = null)Async variant for assertions that involve await:
await Track.ThatAsync(async () =>
{
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
});-
Expression capture: C# 10's
[CallerArgumentExpression]captures the source text of the lambda passed toTrack.That()at compile time. -
Formatting:
AssertionExpressionFormattertransforms the raw expression (e.g.response.StatusCode.Should().Be(HttpStatusCode.Created)) into readable English (response status code should be Created). -
PlantUML injection: The formatted text is injected into the sequence diagram as a styled
hnote across <<assertionNote>>viaDefaultTrackingDiagramOverride.InsertPlantUml(). -
Conditional styling: A
<<assertionNote>>PlantUML style (smaller font, rounded corners) is only emitted when assertion notes are present in the diagram.
The formatter handles common FluentAssertions/AwesomeAssertions patterns:
| Raw Expression | Formatted Output |
|---|---|
result.Count.Should().Be(3) |
Result count should be 3 |
order.Status.Should().Be(OrderStatus.Shipped) |
Order status should be Shipped |
items.Should().HaveCount(5) |
Items should have count 5 |
response.Should().BeOfType<OrderResponse>() |
Response should be of type OrderResponse |
list.Should().ContainSingle(x => x.IsAdmin) |
List should contain single x => x.IsAdmin |
result.Should().NotBeNull() |
Result should not be null |
Rules applied:
- Splits on
.Should().— left side becomes the subject, right side becomes the predicate - PascalCase is split into space-separated words (
HaveCount→have count) - Enum prefixes are stripped for simple arguments (
HttpStatusCode.OK→OK) - Generic type arguments are preserved (
BeOfType<string>()→be of type string) -
.And.chains take only the first assertion - Lambdas in arguments are preserved as-is
When any test in the report uses Track.That(), an Assertions: Show / Hide toggle appears in the report toolbar (alongside the existing Details and Headers toggles).
- Default: Hidden — assertion notes are stripped from the diagram source before rendering
- Show: Re-renders all diagrams with assertion notes visible
- The toggle works at both report level (affects all diagrams) and scenario level (affects a single test)
No toggle when unused: If no tests in the report use
Track.That(), the Assertions toggle is not shown.
Track.That() resolves the current test identity via:
-
TestIdentityScope.Current(AsyncLocal — set automatically by framework integrations) -
TestIdentityScope.GlobalFallback(static — useful in single-threaded test runners)
If neither is set, the assertion executes normally but no diagram note is logged. This means Track.That() is safe to use in shared helper methods that may run outside a test context.
Track.That() captures the expression text regardless of which assertion library you use:
// FluentAssertions/AwesomeAssertions
Track.That(() => result.Should().Be(42));
// xUnit Assert
Track.That(() => Assert.Equal(42, result));
// NUnit Assert
Track.That(() => Assert.That(result, Is.EqualTo(42)));
// Shouldly
Track.That(() => result.ShouldBe(42));The AssertionExpressionFormatter produces the best output for FluentAssertions/AwesomeAssertions .Should(). patterns. For other libraries, it falls back to displaying the raw expression text (which is still readable and useful).
Getting 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