Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
History note: All version sections were reformatted on 2026-07-05 for one-time CONVENTIONS §CHANGELOG conformance: forbidden sub-headers folded into the six Keep a Changelog headers, non-user-facing content removed (internal refactors, test counts, coverage numbers, CI and build hygiene, governance churn, roadmap notes), bullets kept in past-tense active voice with code-formatted API leads. The nuget.org Release Notes tab and the GitHub Release for each shipped version are unchanged. A CI
family-lintgate keeps future sections conforming; each is frozen per Rule 7 once shipped.
Unreleased
0.2.0 - 2026-06-14: kind, root, event, and count assertions; sampling control
Minor release. Adds span and capture assertions for ASP.NET Core span testing, plus a sampling-control capture overload. Purely additive.
Added
- Span assertions:
Assert.That(span).HasKind(ActivityKind)(for exampleServerfor an inbound request span),IsRoot()(no parent),HasEvent(name), andHasExceptionEvent()(the OpenTelemetry"exception"event). The event assertions list the span's event names on failure. - Capture assertions:
Assert.That(capture).HasNoSpan(operationName)(the inverse ofHasSpan, for asserting an operation was never traced) andHasSpanCount(int). SpanCapture.ForSource(name, ActivitySamplingResult)andForSources(ActivitySamplingResult, params string[])capture under a chosen sampling result. The existing parameterless forms still forceAllDataAndRecorded. A lower result (for examplePropagationData) lets a test exercise code that branches onActivity.IsAllDataRequested, with the documented caveat that an activity's effective sampling is the maximum across all active listeners, so this takes effect only when the capture is the sole listener.
0.1.2 - 2026-06-06: package description correction
Metadata-only release. No API or behavior change.
Changed
.Because(reason): added a README example showing it chained on a span assertion. Inherited from TUnit's base assertion type and has always worked on the generated span assertions; the note makes that explicit.
Fixed
- Corrected the NuGet package
<Description>. It described a foundation release carrying onlyHasOperationNameand said the full fluent surface "lands in 0.1.0"; the package has shipped the complete surface (operation name, tag existence and value, status, parent/child, same-trace) since 0.1.0. The description now matches the README.
0.1.1 - 2026-06-05: documentation refresh
Documentation-only release. No API or behavior change.
Changed
- Refreshed the README (plain-ASCII punctuation).
0.1.0 - 2026-06-04: span-query surface and the full assertion set
Minor release. Completes the foundation surface with multi-source capture, the span-query helpers, and
the tag / status / parent-child / same-trace assertions plus a capture-level HasSpan. Purely
additive; the 0.0.1 ApiCompat baseline is preserved.
Added
- Core
TracingAssertions:SpanCapture.ForSources(params string[])captures from any of several namedActivitySources.SpanCapture.FindByOperationName(name)returns the first captured span with that operation name.SpanCapture.FindByOperationNameAndTag(name, tagKey, tagValue)returns the first captured span with that operation name carrying a matching tag (tag value compared by invariantToString).SpanCapture.ChildrenOf(parent)returns the captured direct children of a span (same trace,ParentSpanIdequals the parent'sSpanId).
- Adapter
TracingAssertions.TUnit(generated via[GenerateAssertion]):Assert.That(span).HasTag(key)asserts a tag is present.Assert.That(span).HasTagValue(key, value)asserts a tag's value (compared by invariantToString). Named distinctly fromHasTag(key)so a two-argument call is never silently bound to the tag-existence overload.Assert.That(span).HasStatus(ActivityStatusCode)asserts the span status.Assert.That(span).IsChildOf(parent)asserts a single-hop parent/child relationship in the same trace.Assert.That(span).SharesTraceWith(other)asserts two spans share aTraceId.Assert.That(capture).HasSpan(operationName)asserts the capture contains a span with that operation name, listing the captured names on failure.
0.0.1 - 2026-06-04: foundation release
First published release. It establishes the repository, the CI and release pipeline, and the two
NuGet package identities (TracingAssertions core, TracingAssertions.TUnit adapter) with a minimal
but real surface. The fuller span-query surface and the broader fluent assertions land in 0.1.0.
Added
- Core
TracingAssertions:SpanCapture.ForSource(name)starts a rawActivityListener(samplingAllDataAndRecorded) over a singleActivitySourceand collects stoppedSystem.Diagnostics.Activityspans intoCaptured; disposing the capture detaches the listener. No OpenTelemetry SDK, no exporter pipeline, and no NuGet runtime dependency (System.Diagnostics.DiagnosticSourceis in the shared framework). - Adapter
TracingAssertions.TUnit: theHasOperationNamespan assertion, generated via TUnit's[GenerateAssertion]source generator, usable asawait Assert.That(span).HasOperationName("..."). - Both packages are AOT-compatible and trimmable, with no runtime reflection in the assertion path.