Programming and Software Development

How Microsoft.Testing.Platform Turns Failed Test Results into Actionable Evidence

The .NET Blog presents practical practices for using Microsoft.Testing.Platform to improve test reporting in GitHub Actions and Azure DevOps by distinguishing regressions from flaky failures and preserving evidence when the test host crashes. It also explains how to choose report formats, centralize repository-level settings, and avoid compatibility issues and duplicate result publishing.

2026-08-06
6 min read
10 views
فريق تحرير certi.news
How Microsoft.Testing.Platform Turns Failed Test Results into Actionable Evidence

The problem is not that a build turns red by itself, but knowing whether the cause is a new regression, a flaky test, or a test-host crash that removed the evidence needed for investigation. The .NET Blog explains how Microsoft.Testing.Platform, or MTP, can make test reports more useful to developers, reviewers, and continuous integration tools, rather than merely displaying a long list of logs.

These practices target teams using GitHub Actions or Azure DevOps that want failure information to reach the decision point within a pull request. The platform also makes it possible to produce multiple report formats from a single run and provide structured outputs that programs, dashboards, and development tools can consume consistently.

Use build history to distinguish regressions from flaky failures

Azure DevOps already displays test evidence in the Tests tab, but passing a historical window to the reporter adds context to each failure. When using the option --report-azdo-flaky-history 14, the platform queries the pipeline history over 14 days, then distinguishes a test that failed intermittently from a test without a comparable history.

A flaky test can appear with the label [flaky: failed 3/20 in last 14d], while a failure without this record receives the label [REGRESSION]. This helps the reviewer begin the investigation from the appropriate path: a failure without history needs immediate attention as a potential regression, whereas a recurring failure starts from its known record.

If the team wants to change this continuous integration behavior, the option --report-azdo-demote-known-flaky converts known flaky failures into warnings while keeping regressions as errors. However, the source emphasizes that the decision should be explicit: do we want to use history only to guide the reviewer, or do we want it to automatically change the severity of the failure? In the testfx pipeline, historical comments were used while keeping all failure cases as build blockers.

The same history is used to detect slow tests through --report-azdo-slow-test-history. The option compares each test with its previous performance, using a configurable multiplier and a minimum number of runs so that a single cold run does not trigger an inaccurate alert.

Preserve evidence when the test host crashes

TRX results used to be serialized at the end of the run, so a severe crash could result in the loss of the entire report. Results are now written to disk as they are produced, and together with the crash-dump extension, the partial report can be finalized when the host stops:

dotnet test --report-trx --crashdump

This produces a valid TRX file containing all tests that completed, along with a list of the tests that were running when the crash occurred. The extension also writes a file with the .crash.sequence.log extension that records the start and end of each test, helping identify the test that started but did not finish even when multiple tests run in parallel.

Attachments are handled as well. Crash dumps, stop comments, and test-extension files are no longer silently discarded on .NET Framework when the path exceeds the Windows MAX_PATH limit. If an attachment cannot be copied, this appears in the console instead of being mentioned only inside the TRX file. The result is that an incomplete run is clearly shown as incomplete, rather than appearing as a green report that hides missing evidence.

Choose the report format according to its consumer

A single run can enable multiple formats without a separate conversion step. TRX is suitable for .NET tools, while HTML is useful for direct inspection, and JUnit XML and CTRF JSON are useful for dashboards and cross-technology automation. CTRF provides a shared JSON schema for aggregating .NET results with results from other languages.

Continuous integration systems read TRX and JUnit in result views, while HTML and CTRF appear as files that can be downloaded or used in dashboards. In Azure DevOps, the option --report-azdo-upload-artifacts files can automatically upload result-evidence files. Files should also be named using the option --report-<format>-filename and placeholders such as {asm} and {tfm}, so that results do not conflict in projects targeting multiple frameworks.

Make outputs stable and automatable

The option --list-tests json provides a versioned-schema document describing discovered tests and their source locations. This serves as a stable input for test selection, change-impact analysis, and development-environment integration, instead of parsing console text that may change between releases.

MTP outputs also adapt to agent and language-model environments by hiding the banner, ANSI characters, and progress animation, and by displaying stdout and stderr for failed tests only by default. The behavior can be controlled through NO_COLOR and the --ansi and --progress options.

Centralize the reporting policy and verify compatibility

The article recommends trying MTP 2.3 or later in one test project, then enabling --report-gh in GitHub Actions or --report-azdo in Azure DevOps. After choosing the policy, settings are saved in a testconfig.json file inside the repository so that local runs and CI runs produce the same reports. Directory.Build.props can also be used to apply consistent settings to all test projects, or the AllMicrosoft profile can be used to enable the stable set of extensions, while JUnit and CTRF remain optional.

Teams that do not use MSTest.Sdk should verify that reporter package versions match the MTP version targeted by the test framework. MTP 2.x support extends to MSTest.TestAdapter 4.0.0, NUnit3TestAdapter 6.0.1, TUnit 1.7.16, YoloDev.Expecto.TestSdk 0.16.0, and preview versions of xunit.v3 4.0. The solution also does not support mixing MTP and VSTest projects, so MTP participation should be configured at the repository level.

Azure DevOps history options require the token SYSTEM_ACCESSTOKEN: $(System.AccessToken). Without it, the run continues but skips historical comments. In existing pipelines, test-result publishing and file-publishing tasks can be replaced with the corresponding MTP options, but code-coverage publishing is not replaced; therefore, PublishCodeCoverageResults@2 must be kept. Direct publishing should also not be enabled together with PublishTestResults@2, because that creates two separate test runs for the same build.

News source
ف
Author

فريق تحرير certi.news

In the same category

You may also like

View all news