February 10th, 2025

Microsoft.Testing.Platform: Now Supported by All Major .NET Test Frameworks

Amaury Levé
Senior Software Engineer

A year ago, we launched Microsoft.Testing.Platform as part of the MSTest Runner announcement. Our goal was to create a reliable testing platform for .NET projects, focused on extensibility and modularity.

We are excited to announce that Microsoft.Testing.Platform has now reached 20 Million+ downloads. We are thrilled to see the adoption of the platform by all major .NET test frameworks. Whether you are using Expecto, MSTest, NUnit, TUnit, or xUnit.net, you can now leverage the new testing platform to run your tests.

In this post, we’ll highlight the test frameworks that have embraced Microsoft.Testing.Platform, share their unique characteristics, and provide resources for getting started.

What is Microsoft.Testing.Platform

Microsoft.Testing.Platform 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 Microsoft.Testing.Platform is embedded directly in your test projects, and there’s no other app dependencies, such as vstest.console or dotnet test needed to run your tests.

Microsoft.Testing.Platform is open source. To submit an issue or contribute to the project, you can find Microsoft.Testing.Platform code in microsoft/testfx GitHub repository.

Key features

Microsoft.Testing.Platform is designed as a modular and extensible testing platform, allowing you to include only the components you need and to extend any part of the test execution.

The core platform is designed to be portable and dependency-free allowing you to produce test applications that can run anywhere .NET is supported. Microsoft.Testing.Platform is also integrated with Visual Studio Test Explorer, VS Code Test Explorer in C# Dev Kit, Azure DevOps and .NET SDK providing a seamless experience for developers.

Additional resources

Enabling Microsoft.Testing.Platform in your favorite test framework

The test frameworks are ordered alphabetically.

All examples below will assume the following production source code:

Contoso.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Calculator.cs:

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

Expecto

Expecto aims to make it easy to test CLR based software; be it with unit tests, stress tests, regression tests or property based tests. Expecto tests are parallel and async by default, so that you can use all your cores for testing your software. This also opens up a new way of catching threading and memory issues for free using stress testing.

With the release of v0.15.0, YoloDev.Expecto.TestSdk now supports running test through the new testing platform. To opt-in, simply edit your project’s project file to set <EnableExpectoTestingPlatformIntegration>true</EnableExpectoTestingPlatformIntegration> and <OutputType>Exe</OutputType>.

Expecto Sample Application

Contoso.Tests.fsproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>

    <EnableExpectoTestingPlatformIntegration>true</EnableExpectoTestingPlatformIntegration>
    <OutputType>Exe</OutputType>
    <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="YoloDev.Expecto.TestSdk" Version="0.15.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Contoso\Contoso.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Compile Include="Test.fs" />
  </ItemGroup>

</Project>

Test.fs:

module Contoso.Tests

open Expecto

[<Tests>]
let tests =
    testList "Calculator Tests" [
        test "Add function returns sum" {
            let calculator = Calculator()
            let result = calculator.Add(1, 2)
            Expect.equal result 3 "Expected sum to be 3"
        }
    ]

MSTest

MSTest, Microsoft Testing Framework, is a fully supported, open source, and cross-platform test framework with which to write tests targeting .NET Framework, .NET Core, .NET, UWP, and WinUI on Windows, Linux, and Mac.

With v3.2.0 or later, MSTest.TestAdapter supports running tests through the new testing platform. To opt-in, simply edit your project’s project file to set <EnableMSTestRunner>true</EnableMSTestRunner> and <OutputType>Exe</OutputType>.

MSTest Sample Application

Contoso.Tests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>        

    <EnableMSTestRunner>true</EnableMSTestRunner>
    <OutputType>Exe</OutputType>
    <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MSTest" Version="3.7.3" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Contoso\Contoso.csproj" />
  </ItemGroup>

</Project>

Test.cs:

[TestClass]
public class CalculatorTests
{
    [TestMethod]
    public void Add_WhenCalled_ReturnsSum()
    {
        var calculator = new Calculator();
        var result = calculator.Add(1, 2);

        Assert.AreEqual(3, result);
    }
}

NUnit

NUnit is a unit-testing framework for all .NET languages. Initially ported from JUnit, the current production release has been completely rewritten with many new features and support for a wide range of .NET platforms.

With the release of v5, NUnit3TestAdapter now supports running test through the new testing platform. To opt-in, simply edit your project’s project file to set <EnableNUnitRunner>true</EnableNUnitRunner> and <OutputType>Exe</OutputType>.

NUnit Sample Application

Contoso.Tests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>        

    <EnableNUnitRunner>true</EnableNUnitRunner>
    <OutputType>Exe</OutputType>
    <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
    <PackageReference Include="NUnit" Version="4.3.2" />
    <PackageReference Include="NUnit.Analyzers" Version="4.6.0"/>
    <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Contoso\Contoso.csproj" />
  </ItemGroup>

</Project>

Test.cs:

public class CalculatorTests
{
    [Test]
    public void Add_WhenCalled_ReturnsSum()
    {
        var calculator = new Calculator();
        var result = calculator.Add(1, 2);

        Assert.That(result,Is.EqualTo(3));
    }
}

TUnit

TUnit is a modern, flexible and fast testing framework for C#, featuring with Native AOT and Trimmed Single File application support! This new test framework is built solely on top of Microsoft.Testing.Platform.

TUnit Sample Application

Contoso.Tests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="TUnit" Version="0.8.4" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Contoso\Contoso.csproj" />
  </ItemGroup>

</Project>

Test1.cs:

public class CalculatorTests
{
    [Test]
    public async Task Add_WhenCalled_ReturnsSum()
    {
        var calculator = new Calculator();
        var result = calculator.Add(1, 2);

        await Assert.That(result).IsEqualTo(3);
    }
}

xUnit.net

xUnit.net is a free, open source, community-focused unit testing tool for the .NET Framework. Written by the original inventor of NUnit v2, xUnit.net is the latest technology for unit testing C#, F#, VB.NET and other .NET languages.

With the release of xunit.v3, xUnit.net now supports running test through the new testing platform. To opt-in, simply edit your project’s project file to set <UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>.

xUnit.net Sample Application

Contoso.Tests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable> 

    <UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
    <OutputType>Exe</OutputType>
    <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="xunit.v3" Version="1.0.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="3.0.1" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Contoso\Contoso.csproj" />
  </ItemGroup>

</Project>

Test.cs:

public class CalculatorTests
{
    [Fact]
    public void Add_WhenCalled_ReturnsSum()
    {
        var calculator = new Calculator();
        var result = calculator.Add(1, 2);

        Assert.Equal(3, result);
    }
}

Looking Ahead

We would like to extend our heartfelt appreciation to the framework authors we have collaborated with and continue to work closely with. We are thrilled to witness the ongoing evolution of this platform and its ability to empower developers. We eagerly anticipate numerous contributions from the community and look forward to the innovative extensions that will be created.

If you haven’t already, we encourage you to explore the platform, experiment with your preferred framework, and share your feedback.

Together, let’s continue to build an outstanding .NET testing ecosystem!

Author

Amaury Levé
Senior Software Engineer

12 comments

  • Michael Dietrich

    Thank you for all the insights. This is very helpful together with all the comments and answers.

    Something I wonder, what is the purpose of the Microsoft.NET.Test.Sdk NuGet when MTP is used?
    In the examples it looks like it is necessary for NUnit and xUnit, but not for TUnit and MSTest. Is there a reason for this?

    It also seems that OutputType Exe needs to be always added, is there a reason it is not automatically inferred when any of the test framework switches such as UseMicrosoftTestingPlatformRunner is being used?

    • Amaury LevéMicrosoft employee Author

      The `Microsoft.NET.Test.Sdk` package is not needed for MTP as it's linked to VSTest. This is declared for NUnit, xUnit and (transitively) for MSTest to ensure older versions of Test Explorer can fallback to VSTest mode and to fallback to VSTest if you disable dotnet test support (`TestingPlatformDotnetTestSupport`). For TUnit, it's not declared because this new test framework is only built on top of MTP.

      > It also seems that OutputType Exe needs to be always added, is there a reason it is not automatically inferred when any of the test framework switches such as UseMicrosoftTestingPlatformRunner is being used?

      We wanted to have...

      Read more
  • Laszlo Deak

    What is the strategy to run these tests in a solution with multiple test projects? Would dotnet run or dotnet test work on a solution file? What is the strategy to migrate existing extensions of vstest: loggers, coverage, etc.?

    Is this more of a viable alternative for smaller projects with single test assembly? What are the benefits (differences) to vstest? How can I decide which one to use?

    • Amaury LevéMicrosoft employee Author

      > What is the strategy to run these tests in a solution with multiple test projects?
      The recommended strategy is to use `dotnet test`. At the moment, the experience is not ideal because `dotnet test` wasn't designed with extensibility in mind so we had to hack our way for MTP but we are working on a new improved experience that will ship with .NET 10 SDK (see https://github.com/dotnet/sdk/issues/45927).

      > Would dotnet run or dotnet test work on a solution file?
      `dotnet run` doesn't support running on solution (but there is a request for it, see https://github.com/dotnet/sdk/issues/46323).

      > What is the strategy...

      Read more
      • Laszlo Deak

        Thank you for the comprehensive response.

  • Michael Taylor

    I'm also confused about the `TestingPlatformDotnetTestSupport` property. Currently we use MSTest and we have `EnableMSTestRunner` set based upon the original article. Are we using the new MS test platform? If so then why is this other property needed. Why doesn't the MSTest package we include set this for us? Isn't it up to the underlying test runner to determine whether it supports it or not and not something we should set in our code?

    Another thing I wonder about is why other test platforms aren't using `EnableMSTestRunner` property? In the xUnit case the property is called `UseMicrosoftTestingPlatformRunner` instead. Since each project...

    Read more
    • Amaury LevéMicrosoft employee Author

      > Are we using the new MS test platform?
      Yes you are! `EnableMSTestRunner` opts-in the support of MTP when running tests through `dotnet run`, in Test Explorer or by calling the exe directly. If you want to also use MTP when calling `dotnet test`, you have to set `TestingPlatformDotnetTestSupport` to `true`. We decided to have a different opt-in because `dotnet test` is hardcoded toward VSTest and there is no easy way to plug a different test platform so you can end up with confusing behaviors. For example, `dotnet test --collect "Code Coverage"` will not process code coverage for the new...

      Read more
  • Alireza

    `TestingPlatformDotnetTestSupport`

    Who named this? Robert Martin?

  • bolontiku · Edited

    I don’t think your F# code compiles at all.

    Also can you please explain in more detail, what below settings enable?

    What these settings enable?

    EnableExpectoTestingPlatformIntegration
    TestingPlatformDotnetTestSupport

    • Amaury LevéMicrosoft employee Author

      > I don’t think your F# code compiles at all.
      You are correct! I am sorry I didn't review the code when working on a simpler version. I'll work on submitting a fix for the blogpost tomorrow.

      > Also can you please explain in more detail, what below settings enable?
      Yes, see my reply for each entry below:

      > EnableExpectoTestingPlatformIntegration
      `YoloDev.Expecto.TestSdk` relies by default on VSTest as the test platform. By setting this property to true, you are saying that you want to use MTP as the test platform.

      > TestingPlatformDotnetTestSupport
      `dotnet test` is tight to VSTest and will call this platform by...

      Read more
      • bolontiku 1 week ago · Edited

        This comment doesn’t allow me to reply below.
        While now it compiles and runs
        TestingPlatformDotnetTestSupport
        switch effectively makes tests non discoverable for ionide and vscode when you use F#.
        It could be a ionide thing perhaps.

      • Amaury LevéMicrosoft employee Author 1 week ago

        There were some issues with the update of the blogpost but it’s now all good. Please let me know if you have some more question.