Skip to content

Test class name missing in TRX report for parametrized fixture when running through MTP #1351

@radim-bernatik-veeam

Description

@radim-bernatik-veeam

In the following example is situation, when class name is not fully included in resulting TRX report. Only the namespace of the class is included, but the class name is missing. There are newest packages for MTP (2.0.1) and NUnit3TestAdapter (6.0.0-beta.1). But the problem was firstly recognized by me on MTP/1.8.1 and NUnit3TestAdapter/5.0.1. I also checked NET 8 and NET 10 rc1 frameworks, issue is reproducible on both.

In the TRX report for both instances of the Test1 test is only className="One", when running using MTP.
The TRX report fragment:

    <UnitTest name="Test1" storage="d:\git\mtp\one\bin\debug\net10.0\one.dll" id="f250b33b-8a35-b41a-e7bf-8e9547f93a26">
      <Execution id="983facad-df20-4239-a725-afd3d6150424" />
      <TestMethod codeBase="D:\Git\MTP\One\bin\Debug\net10.0\One.dll" adapterTypeName="executor://NUnitExtension/1.0.0+c7d97261880dc4b9bcf3f48c2cabc5293016adba" className="One" name="Test1" />
    </UnitTest>

Execution command: dotnet exec One\bin\Debug\net10.0\One.dll --results-directory TestResults --report-trx

On the other side, when same example is executed by vstest.console.exe command, the TRX report contains proper className="One.Tests(One)" and className="One.Tests(Two)".
The TRX report fragment:

  <TestDefinitions>
    <UnitTest name="Test1" storage="d:\git\mtp\one\bin\debug\net10.0\one.dll" id="31e09d51-24f9-f1bf-3546-ea0d27e9d1e2">
      <Execution id="205cb3bb-29b2-47ff-8f7a-16721f04c50a" />
      <TestMethod codeBase="D:\Git\MTP\One\bin\Debug\net10.0\One.dll" adapterTypeName="executor://nunit3testexecutor/" className="One.Tests(One)" name="Test1" />
    </UnitTest>
    <UnitTest name="Test1" storage="d:\git\mtp\one\bin\debug\net10.0\one.dll" id="b28b10d5-d1e1-b8e3-f896-8c4751d57b96">
      <Execution id="8cd2ab2d-6490-4b08-8438-500a777931a3" />
      <TestMethod codeBase="D:\Git\MTP\One\bin\Debug\net10.0\One.dll" adapterTypeName="executor://nunit3testexecutor/" className="One.Tests(Two)" name="Test1" />
    </UnitTest>
  </TestDefinitions>

Execution command: vstest.console.exe One\bin\Debug\net10.0\One.dll /logger:trx

In the example code bellow there are two TestFixtureData provider methods, one with used SetArgDisplayNames method, and one without. Reports above are from usage the one with custom test data names GetTestCasesWithNames. But this has no impact on the results. Even if test data contains custom name or not, or even if TestFixture attributes is used directly with parameters, in all cases the .Tests(One) or .Tests(1) is missing from the TRX report's TestMethod node className attribute value (when MTP is used, old vstest.console.exe runner works without issues in all cases).

I don't know if this issue is in MTP or NUnit3TestAdapter code, but I guess the NUnit3TestAdapter one, because the strange behavior is triggered by usage of parametrized fixture attributes.

I think this issue is quite critical, because it prevents usage of parametrized fixtures in MTP. When class name is not fully recognized in TRX report, we cannot map the test result to proper source file and address possible issues. It also leads to test method name misidentification because the class name is missing from the full tests name. It is nowhere in TRX report.

Example unit test class - UnitTest1.cs

using NUnit.Framework;
using System.Collections;

namespace One
{
    //[TestFixture(1)]
    //[TestFixture(2)]
    //[TestFixtureSource(nameof(GetTestCases))]
    [TestFixtureSource(nameof(GetTestCasesWithNames))]
    public class Tests
    {
        private int _counter;

        public Tests(int counter)
        {
            _counter = counter;
        }

        [Test]
        public void Test1()
        {
            Console.WriteLine($"Test1:{_counter}");
            Assert.Pass();
        }

        private static IEnumerable<TestFixtureData> GetTestCases()
        {
            yield return new TestFixtureData(1);
            yield return new TestFixtureData(2);
        }

        private static IEnumerable<TestFixtureData> GetTestCasesWithNames()
        {
            yield return new TestFixtureData(1).SetArgDisplayNames("One");
            yield return new TestFixtureData(2).SetArgDisplayNames("Two");
        }
    }
}

Example project file - One.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
    <EnableNUnitRunner>true</EnableNUnitRunner>
    <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="coverlet.collector" Version="6.0.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
    <PackageReference Include="NUnit" Version="3.12.0" />
    <PackageReference Include="NUnit.Analyzers" Version="3.8.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="6.0.0-beta.1" />
    <PackageReference Include="Microsoft.Testing.Extensions.Telemetry" Version="2.0.1" />
    <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Version="2.0.1" />
    <PackageReference Include="Microsoft.Testing.Extensions.VSTestBridge" Version="2.0.1" />
    <PackageReference Include="Microsoft.Testing.Platform" Version="2.0.1" />
    <PackageReference Include="Microsoft.Testing.Platform.MSBuild" Version="2.0.1" />
  </ItemGroup>
</Project>

Metadata

Metadata

Assignees

No one assigned

    Labels

    InvestigateMTPMicrosoft Test Platform related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions