This package provides Open Telemetry for the platform. Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device.
Get Started
| Product | Versions |
|---|---|
| .NET | |
| .NET Standard |
README
Microsoft.Testing.Extensions.OpenTelemetry
Microsoft.Testing.Extensions.OpenTelemetry is an extension for Microsoft.Testing.Platform that instruments test execution with OpenTelemetry-compatible traces and metrics.
Microsoft.Testing.Platform is open source. You can find Microsoft.Testing.Extensions.OpenTelemetry code in the microsoft/testfx GitHub repository.
Install the package
dotnet add package Microsoft.Testing.Extensions.OpenTelemetry
About
This package extends Microsoft.Testing.Platform with:
- OpenTelemetry integration: exposes the Microsoft Testing Platform activity source and meter (both named
Microsoft.Testing.Platform) so test execution can be observed via the OpenTelemetry .NET SDK. - Application-owned diagnostics:
AddTestingPlatformDiagnostics()activates the source and meter without constructing or owning an OpenTelemetry SDK provider, so test applications can use the provider configured by Aspire ServiceDefaults or any other host-level observability setup. - Semantic conventions: where an OpenTelemetry convention exists it is used verbatim —
test.case.name,test.case.result.status(upstreampass/fail),test.suite.name,code.function.name,code.file.path,code.line.number,code.stacktrace,error.type, plus anexceptionspan event and anErrorspan status on failures. The pre-existing attribute and instrument names are still emitted by default so existing dashboards keep working; setTESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0to drop them. - Platform extensions: OpenTelemetry does not define any
test.*metrics or test-case span conventions (as of semantic conventions 1.43.0), andtest.case.result.statusupstream only definespassandfail. The instruments listed below, the additional result statuses (skipped,error,timeout,cancelled,unknown),cicd.provider.name, and thetest.case.*attributes not listed above are therefore Microsoft.Testing.Platform extensions, deliberately placed in the namespace where an upstream definition would land. - Composable resource attributes:
AddTestingPlatformTestResource()adds test-specific identity andAddTestingPlatformCIResource()adds CI/source-control provenance without changing application-owned service, host, OS or process identity.AddTestingPlatformResource()remains the standalone aggregate convenience path for test assembly, service, host, OS, runtime, CI provider, pipeline run, branch and commit. - Turnkey configuration:
AddOpenTelemetryProviderFromEnvironment()wires instrumentation, resource and an OTLP exporter purely from the standardOTEL_*environment variables, so a run can be exported without writing configuration code. - Trace context propagation: when the process that started the test run publishes a
TRACEPARENTenvironment variable (CI runners,dotnet test, IDEs), the whole run nests under that trace instead of starting an orphan one. - Lifecycle management: ties the lifetime of a
TracerProviderandMeterProviderto the test application, so they are disposed alongside the test host. - Observability: lets you route test execution data, via your own OpenTelemetry exporter configuration, into observability backends (e.g. Jaeger, Prometheus, Grafana).
- Standards-based: leverages the OpenTelemetry .NET SDK so that data is sent only to the telemetry exporters and endpoints that you configure.
Note:
AddOpenTelemetryProviderdoes not register any instrumentation or exporter by default. To actually collect MTP telemetry you must, from thewithTracing/withMetricsdelegates:
- call
AddTestingPlatformInstrumentation()on both theTracerProviderBuilderand theMeterProviderBuilderto subscribe to the Microsoft Testing Platform source/meter, and- register at least one exporter (for example
AddOtlpExporter,AddConsoleExporter, or a vendor-specific exporter).Without instrumentation, no MTP activities or metrics are collected; without an exporter, collected telemetry is not emitted anywhere.
Use
AddOpenTelemetryProviderFromEnvironment()instead if you want all of that configured for you from the standardOTEL_*variables. It only installs the instrumentation when an exporter is actually configured (viaOTEL_TRACES_EXPORTER/OTEL_METRICS_EXPORTER/OTEL_EXPORTER_OTLP_ENDPOINT) or when you pass a configuration delegate, so leaving it inProgram.csunconditionally costs nothing on machines that do not opt in.
Use an application-owned OpenTelemetry provider
When the test application already configures OpenTelemetry through Aspire ServiceDefaults, OpenTelemetry.Extensions.Hosting, or another application-level composition root, use Microsoft.Testing.Extensions.Hosting to preserve that ownership while MTP runs:
dotnet add package Microsoft.Testing.Extensions.Hosting
dotnet add package Microsoft.Extensions.Hosting
HostApplicationBuilder hostBuilder = Host.CreateApplicationBuilder(args);
hostBuilder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource
.AddService("MyTestApplication")
.AddTestingPlatformTestResource()
.AddTestingPlatformCIResource())
.WithTracing(tracing => tracing.AddTestingPlatformInstrumentation())
.WithMetrics(metrics => metrics.AddTestingPlatformInstrumentation());
using IHost host = hostBuilder.Build();
return await host.RunTestingPlatformAsync(args, testBuilder =>
{
// Register the test framework here.
testBuilder.AddTestingPlatformDiagnostics();
});
AddTestingPlatformDiagnostics() does not build, configure, flush, or dispose a TracerProvider or MeterProvider. The application keeps full ownership of those providers and their exporters. The older AddOpenTelemetryProvider() and AddOpenTelemetryProviderFromEnvironment() helpers remain available as standalone convenience paths when the test application wants MTP to own the provider lifetime.
For an MSBuild-generated hosted entry point, set:
<PropertyGroup>
<TestingPlatformHostFactory>Contoso.Tests.TestHost.CreateHost</TestingPlatformHostFactory>
<TestingPlatformOpenTelemetryMode>HostOwned</TestingPlatformOpenTelemetryMode>
</PropertyGroup>
HostOwned contributes one generated builder hook that calls only AddTestingPlatformDiagnostics(). It does not create providers or exporters and does not replace the host's service.name, host, OS, or process resource identity.
The focused resource helpers are recommended when Aspire ServiceDefaults, HostApplicationBuilder, or another application-level composition root already owns service.*, host.*, os.*, and process.*. Use AddTestingPlatformResource() only when the test application wants the extension to configure that complete standalone resource identity.
See the complete HostApplicationBuilder sample.
Native MSTest uses one MTP-owned activity for each test execution. MSTest makes that activity current only while the
test's constructor, test initialization, test method, cleanup, and custom TestMethodAttribute code execute, so
automatic HttpClient, SQL, Entity Framework, WCF, and custom activities become children of the test activity. MTP
then adds the reported result attributes, status, output, artifacts, and timing to that same activity and stops it
with the execution-end timestamp recorded by MSTest. The asynchronous result queue therefore does not inflate the
test duration, and no duplicate MSTest.TestMethod plus MTP result spans are emitted.
Frameworks that do not participate in this internal execution-lease integration keep the existing compatibility
behavior demonstrated by the sample: the framework's execution activity and MTP's test-result activity remain
siblings under TestFramework, and the result activity carries an ActivityLink to the activity that was current
when the framework published the in-progress update. MTP never reparents an asynchronously consumed result to
whatever activity happens to be current on the message-bus thread.
Emitted metrics
| Instrument | Type | Unit | Description |
|---|---|---|---|
test.case.duration |
Histogram | s |
Duration of a single test case, dimensioned by test.case.result.status and test.suite.name. |
test.case.result.count |
Counter | {test} |
Number of test cases, dimensioned by test.case.result.status and test.suite.name. |
test.case.active |
UpDownCounter | {test} |
Test cases currently running. |
test.run.duration |
Histogram | s |
Duration of the whole run, dimensioned by test.run.result.status and test.run.exit_code. |
test.case.retry.count |
Counter | {test} |
Test cases scheduled for a retry attempt (requires Microsoft.Testing.Extensions.Retry). |
Metric dimensions are deliberately kept low-cardinality. Unbounded values such as the per-run test counts are set on
the root span (test.run.total, test.run.failed, test.run.skipped) rather than used as metric dimensions.
Span durations are reported in milliseconds under test.case.duration_ms, distinct from the seconds-valued
test.case.duration metric.
The legacy tests.discovered / tests.started / tests.completed / tests.passed / tests.failed / tests.skipped / tests.unknown counters and the tests.duration histogram (in milliseconds) are still emitted unless legacy attributes are disabled.
Configuration
| Environment variable | Default | Meaning |
|---|---|---|
TRACEPARENT / TRACESTATE |
unset | W3C trace context to nest the run under. |
TESTINGPLATFORM_OTEL_CAPTURE_TEST_OUTPUT |
1 |
Attach captured stdout/stderr to test spans. Set to 0 when the output can contain secrets. |
TESTINGPLATFORM_OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT |
8192 |
Maximum characters kept for a single string attribute. Applies to both the semantic-convention and the legacy attribute names. |
TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES |
1 |
Emit the pre-semantic-convention attribute and instrument names alongside the new ones. |
OTEL_SDK_DISABLED, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTER |
unset | Standard OpenTelemetry variables honored by AddOpenTelemetryProviderFromEnvironment. |
Data exported and controlling sensitive values
Telemetry is only ever sent to the exporters and endpoints you configure — nothing leaves the process unless you register an exporter (directly, or via AddOpenTelemetryProviderFromEnvironment and the OTEL_* variables). Once an exporter is configured, the following attributes can carry environment-specific or sensitive values, so review them against your exporter's destination:
| Attribute (and legacy twin) | Carries | Control |
|---|---|---|
test.case.name (test.name) |
The test's framework-provided display name, which for parameterized or data-driven tests can embed argument values or other user data. Exported verbatim (not truncated). | Emitted for every test. Disable the legacy twin with TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0. |
test.case.id / test.case.parent.id (test.id / test.parent.id) |
The framework-provided test UID(s), which can embed parameter values. Exported verbatim (not truncated). | test.case.id is emitted for every test; test.case.parent.id is emitted when the test has a parent. Disable the legacy twins with TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0. |
test.step.<id>.description (test.step<id>.description) |
Per-step descriptions supplied by the framework. Exported verbatim (not truncated). | Emitted whenever a test reports step timings. Disable the legacy twin with TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0. |
code.file.path (test.file.path), code.line.number (test.line.start/test.line.end) |
Absolute source file path of the test — reveals machine and repository layout. Exported verbatim (not truncated). | On by default whenever a test reports a file location. Disable the legacy twin with TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0. |
test.artifact.file[N].path |
Absolute path of each file artifact a test attaches (dumps, logs, screenshots). Exported verbatim (not truncated). | Emitted whenever a test produces file artifacts. |
test.output.stdout / test.output.stderr (test.stdout / test.stderr) |
Captured standard output and error of the test, which routinely contains secrets or environment data. | Off when TESTINGPLATFORM_OTEL_CAPTURE_TEST_OUTPUT=0; truncated to TESTINGPLATFORM_OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT. |
code.stacktrace, test.case.result.explanation (test.result.explanation), the exception span event (exception.type / exception.message / exception.stacktrace), the span status description, and the legacy test.result.exception.type / test.result.exception.message / test.result.exception.stacktrace |
Exception message and stack-trace text. | Truncated to TESTINGPLATFORM_OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT. Disable the legacy twins with TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0. |
test.metadata.* (test.metadataProperty.*) |
Framework-supplied trait/metadata values, exported verbatim (not truncated). | Emitted whenever a test carries metadata. Disable the legacy twin with TESTINGPLATFORM_OTEL_EMIT_LEGACY_ATTRIBUTES=0. |
Resource vcs.repository.url.full, plus the other resource attributes (host.name, os.description, and in CI the cicd.* / vcs.* pipeline, branch and commit — see Composable resource attributes above) |
The machine, OS and CI provenance attached to every span and metric point. | User-info credentials in the repository URL (https://user:token@host/...) are stripped before export. |
Only the captured output, the result explanation and the exception message and stack trace are truncated to TESTINGPLATFORM_OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT (8192 characters by default); all other listed values are exported verbatim unless the Control column notes otherwise, so truncation is a size guard rather than redaction. Set TESTINGPLATFORM_OTEL_CAPTURE_TEST_OUTPUT=0 on any job whose test output can contain secrets, and prefer sending telemetry to a backend you control.
Documentation
For this extension, see https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-open-telemetry.
For comprehensive documentation, see https://aka.ms/testingplatform.
Feedback & contributing
Microsoft.Testing.Platform is an open source project. Provide feedback or report issues in the microsoft/testfx GitHub repository.
Downloads by Version
Similar & Alternative Packages
Hand-picked matching NuGet libraries based on tags & ecosystem
Depended On By
Find packages that declare this package as a dependency. NuGet does not provide a reverse-dependency endpoint, so candidates are checked on demand.
Adoption Assessment
A verified publisher signal is available. Assess fit from the package's supported frameworks, license and dependency graph rather than popularity alone.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.