NashTech Blog

Azure DevOps integration for Microsoft.Testing.Platform

Table of Contents

Overview

In .NET, a test framework and a test platform are different components that work together to discover and run tests.

  • The test framework defines the test model you write against, such as MSTest, NUnit, xUnit.net, or TUnit.
  • The test platform runs tests, integrates with IDEs and CLI, and provides shared extension points, such as VSTest, Microsoft.Testing.Platform (MTP)

Microsoft.Testing.Platform (MTP) is the new platform for testing from Microsoft. MTP is a lightweight and portable alternative to VSTest for running tests in all contexts, including continuous integration (CI) pipelines, CLI, Visual Studio Test Explorer, and VS Code Text Explorer. The new approach simplifies test execution while providing better performance and diagnostics compared to the VSTest integration method.

Advantages of MTP

1. Faster test execution

One of the biggest improvements is performance as MTP has:

  • faster startup time
  • reduced process overhead
  • less memory usage
  • optimized test discovery

This is especially noticeable for:

  • large solutions
  • CI/CD pipelines
  • repositories with thousands of tests

2. Better extensibility

Instead of one large test platform, MTP allows functionality to be added through extensions, for examples:

  • code coverage
  • test filtering
  • retry logic
  • reporting
  • logging
  • custom diagnostics

This makes it easier for Microsoft and third parties to add features without changing the core platform.

3. Smaller footprint

MTP only loads the components that are actually needed.

  • lower memory usage
  • faster startup
  • simpler dependency graph

4. Better CI/CD experience

Since startup is faster, build pipelines spend less time preparing the test environment. This is particularly beneficial when:

  • many small test projects exist
  • tests are split across multiple jobs
  • cloud runners start from scratch every build

5. Future-focused architecture

Microsoft has indicated that future investments in .NET testing will be centered around MTP rather than VSTest. New testing features are expected to arrive here first.

6. Independent feature delivery

With MTP, features are delivered as NuGet packages rather than being tied to Visual Studio releases can be updated independently, for example:

  • new reporters
  • diagnostics
  • retry support
  • crash dump collection

Update Project .NET 10 SDK to Use MTP

To change a current test project to use MTP, you need to update .csproj file to use NUnit3TestAdapter version 5.0 or greater.

And In a property group (use the top-level one), add the following two properties:

 <PropertyGroup>  
   <EnableNUnitRunner>true</EnableNUnitRunner> <!-- which enables MTP -->
   <OutputType>Exe</OutputType>  <!-- which run as an executable -->
</PropertyGroup>

Starting with .NET 10 SDK, there is native support for MTP. To use it, you must specify the test runner as Microsoft.Testing.Platform in global.json:

{
  "test": {
    "runner": "Microsoft.Testing.Platform"
  }
}

Running Tests in Azure DevOps

Option 1: Use the DotNetCoreCLI task

The DotNetCoreCLI Azure DevOps task now supports Microsoft.Testing.Platform

- task: DotNetCoreCLI@2
  displayName: 'Run tests'
  inputs:
    command: 'test'
    projects: '**/*Tests.csproj'
    arguments: '--no-build --report-trx'

Option 2: Run ‘dotnet test’ directly

You can run the dotnet test command directly using a script or command-line task. This gives you maximum flexibility and doesn’t require specific Azure DevOps task updates.

- task: CmdLine@2
  displayName: 'Run tests'
  inputs:
    script: 'dotnet test --no-build --report-trx'

New options in dotnet test with MTP against VSTest

Refer dotnet test command with Microsoft.Testing.Platform (MTP) – .NET CLI | Microsoft Learn

Retry Tests in Azure DevOps

With Microsoft.Testing.Extensions.Retry extension, you get automatic retry handling with proper Azure DevOps integration; no custom scripting required. However, MTP generates a separate TRX file for each attempt. Previously, the PublishTestResults task treated these as independent test runs, leading to two problems:

  • Incorrect exit codes: The task would fail even when tests eventually passed after retry
  • Confusing UI: Test results appeared as separate runs instead of grouped retry attempts

These issues are solved! The PublishTestResults task now intelligently handles multiple TRX files from retry attempts, correctly grouping them and setting appropriate exit codes.

MTP uses the standard TRX format (also known as VSTest test results format) through the Microsoft.Testing.Extensions.Retry package. The PublishTestResults task has always supported TRX files. What’s new is the intelligent handling of retry scenarios.

Add Retry Nuget packages to your test project

<ItemGroup>
  <PackageReference Include="Microsoft.Testing.Extensions.Retry" Version="2.2.3" />
  <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Version="2.2.3" />
</ItemGroup>

Required ConfigurationTo enable retry-aware test result publishing, set the AllowPtrToDetectTestRunRetryFiles variable to true in your pipeline. This opt-in flag activates the new behavior that correctly interprets multiple TRX files as retry attempts rather than separate test runs.

Complete pipeline example

Here’s a full pipeline demonstrating test execution with retries and proper result publishing:

trigger:
- main

jobs:
- job: MyJob
  variables:
    AllowPtrToDetectTestRunRetryFiles: true

  steps:

  # Your usual steps to install .NET SDK, restore, and build.

  - task: CmdLine@2
    displayName: 'Run tests'
    inputs:
      script: 'dotnet test --no-build --report-trx --retry-failed-tests 3 --results-directory TestResults'

  - task: PublishTestResults@2
    displayName: 'Publish test results'
    inputs:
      testResultsFormat: 'VSTest'
      testResultsFiles: '**/*.trx'
      mergeTestResults: true
      failTaskOnFailedTests: true
    condition: succeededOrFailed()

Picture of Dung Nguyen

Dung Nguyen

I'm be here as a Senior Automation Test Engineer for nearly 10 years. I've experienced on many automation frameworks and tools like Selenium with variety of programming languages, Cypress, RobotFW, TestComplete...I also play more on performance API testing using Jmeter.

Leave a Comment

Suggested Article

Scroll to Top