nunit3-vs-adapter icon indicating copy to clipboard operation
nunit3-vs-adapter copied to clipboard

"Invalid type found in ExtractAllFixtures for test suite" exception with derived TestFixtureType in IFixtureBuilder

Open emz00 opened this issue 2 years ago • 5 comments

  • NUnit 3.13.2, NUnit3TestAdapter 4.2.1
  • Visual Studio 2022 Pro 17.6.7 (but reproducible with dotnet test)
  • .NET 6.0, SDK 8.0 RC1 (but happened with SDK 6.0 and 7.0 too)

I have a custom IFixtureBuilder like this

    [AttributeUsage(AttributeTargets.Class)]
    public class EngineTestFixtureAttribute : NUnitAttribute, IFixtureBuilder
    {
        private class OrderedTestFixture : TestFixture
        {
            public OrderedTestFixture(ITypeInfo fixtureType) : base(fixtureType)
            {
                MaintainTestOrder = true;
            }
        }

        public IEnumerable<TestSuite> BuildFrom(ITypeInfo typeInfo)
        {
...
            var fixture = new OrderedTestFixture(typeInfo);
...
            return new[] {fixture};
        }
    }

When run with dotnet test this fails immediately with the following exception:

Microsoft (R) Test Execution Command Line Tool Version 17.8.0-preview-23421-06 (x64)
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
Exception NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryException,    Exception thrown executing tests in MYTESTS.dll
Invalid type found in ExtractAllFixtures for test suite: OrderedTestFixture
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 217
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 204
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 204
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 204
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 204
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractTestFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 273
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 235
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.ConvertXml(NUnitResults discovery) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 192
   at NUnit.VisualStudio.TestAdapter.NUnitEngine.DiscoveryConverter.Convert(NUnitResults discoveryResults, String assemblyPath) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnitEngine\DiscoveryConverter.cs:line 146
   at NUnit.VisualStudio.TestAdapter.NUnit3TestExecutor.RunAssembly(String assemblyPath, IGrouping`2 testCases, TestFilter filter) in D:\repos\NUnit\nunit3-vs-adapter\src\NUnitTestAdapter\NUnit3TestExecutor.cs:line 286
No test is available in MYTESTS.dll. Make sure that test discoverer & executors are registered and platform & framework version settings are appropriate and try again.

Additionally, path to test adapters can be specified using /TestAdapterPath command. Example  /TestAdapterPath:<pathToCustomAdapters>.

The same code worked with NUnit3TestAdapter 3.17.0 (NUnit 3.12.0).

emz00 avatar Sep 18 '23 08:09 emz00

Looking at the code in https://github.com/nunit/nunit3-vs-adapter/blob/f3b5c9c27490eb81340e09794624aea4d92cf5fe/src/NUnitTestAdapter/NUnitEngine/DiscoveryConverter.cs#L202 it indeed checks for concrete TestFixture types and throws for derived types.

emz00 avatar Sep 18 '23 08:09 emz00

In this case I can work around the issue by creating a normal TestFixture and setting MaintainTestOrder = true using Reflection, but that is, of course a hack, and NUnitTestAdapter should really support derived types as it used to do.

emz00 avatar Sep 18 '23 09:09 emz00

@loop-evgeny Since you find the place where it happened, could you add a test and a fix for the issue as a PR ?

OsirisTerje avatar Sep 26 '23 17:09 OsirisTerje

Maybe! I'd like to, but now that we have a workaround, I'm not sure when I will get around to it.

emz00 avatar Oct 24 '23 15:10 emz00

@OsirisTerje I debugged this a bit, and it seems that it's not that simple. The discovery XML contains <test-suite type="OrderedTestFixture" ... i.e. only my custom type name - we don't know the base type at that point.

I then checked out the old 3.17 version to see how it worked and it takes a completely different code path in Discovery.cs with settings.DiscoveryMethod == DiscoveryMethod.Old. Seems like it relies on NUnitResults.TestCases() to extract the list of test cases, which simply does return TopNode.SelectNodes("//test-case");

So ExtractAllFixtures probably could be made to "work" for this case by treating any unknown type as a TestFixture, but then what if someone else inherits from SetUpFixture, etc.?

Maybe the proper fix would be to write the recognized base type to the discovery XML (and maybe the real type, too, if that's needed for something else), but I'm out of my depth there and would need to get much deeper into the project than I'm likely to have time for any time soon.

emz00 avatar Nov 04 '23 18:11 emz00