Skip to content

--treenode-filter pattern matching is at least non obvious, potentially errored #7300

@mitchcapper

Description

@mitchcapper

Describe the bug

I wanted to run two tests at once, easy enough assumed the OR operator was straightforward but couldn't get it to work.

In short the following filter patterns don't work for selecting two tests (named MyTest1/MyTest2) (and the first one doesn't even work selecting just the one):

/*/*/*/(MyTest1)
/*/*/*/(MyTest1)|(MyTest2)
/*/*/*/(MyTest1|MyTest2)
(/*/*/*/MyTest1)|(/*/*/*/MyTest2) # this one crashes as well

These all work to select both, even though some are a bit non-obvious to me as to why:

/*/*/*/(MyTest1)|(MyTest2*)
/*/*/*/(MyTest1*)|(MyTest2)
/*/*/*/(MyTest1*)|(MyTest2*)
/*/*/*/(MyTest1*)|(MyTest2*)
/*/*/*/(MyTest1*|MyTest2)
/*/*/*/(MyTest1*|MyTest2*)
/*/*/*/MyTest*
/*/*/*/(MyTest1)|(*MyTest2)
/*/*/*/(*MyTest1)|(MyTest2)
/*/*/*/*(MyTest1)|(MyTest2)
/*/*/*/(MyTest1*)|MyTest2
/*/*/*/(MyTest1)|MyTest2*

Here is a short powershell script. I tried to repro without tunit with the TestingPlatformExamples\TestingPlatformExplorer however in VS 2026 while the tests pass they don't have their status picked up and it looks like they haven't run.

Image

Command line works but oddly the command line doesn't show (or accept) the --treenode-filter or --filter to dotnet run -- only --filter-uid even though it looks like the CLI should be included. I tried manually shoehorning it in with

var cliOpts = new TestingFrameworkCommandLineOptions();
testApplicationBuilder.CommandLine.AddProvider(() => cliOpts);
testApplicationBuilder.AddTreeNodeFilterService(cliOpts);

but while it builds still doesnt have the option. I wasn't sure originally if it was a tunit or vstest thing (thomhurst/TUnit#4580) but it seems vstest.

ccdb0ee

Steps To Reproduce

Set-PSDebug -Trace 1
dotnet new console --name YourTestProjectNameHere
cd YourTestProjectNameHere
dotnet add package TUnit --prerelease
rm Program.cs
"namespace YourTestProjectNameHere;`npublic class MyTests {`n    [Test]`n    public async Task MyTest1() => await Assert.That(true).IsTrue();`n    [Test]`n    public async Task MyTest2() => await Assert.That(true).IsTrue();`n}" | Out-File -FilePath MyTests.cs
dotnet run --disable-logo --list-tests
Write-Host -Foreground Red "These Filters fail"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1)|(MyTest2)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1|MyTest2)"
# this fails but crashes dotnet run --disable-logo --treenode-filter "(/*/*/*/MyTest1)|(/*/*/*/MyTest2)"


Write-Host -Foreground Green "These filters work"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1)|(MyTest2*)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1*)|(MyTest2)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1*)|(MyTest2*)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1*)|(MyTest2*)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1*|MyTest2)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1*|MyTest2*)"
dotnet run --disable-logo --treenode-filter "/*/*/*/MyTest*"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1)|(*MyTest2)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(*MyTest1)|(MyTest2)"
dotnet run --disable-logo --treenode-filter "/*/*/*/*(MyTest1)|(MyTest2)"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1*)|MyTest2"
dotnet run --disable-logo --treenode-filter "/*/*/*/(MyTest1)|MyTest2*"

Log of said script attached

out.log

also, with 3 tests it is no more obvious this doesn't work: /*/*/*/(MyTest1|MyTest2|MyTest3) but /*/*/*/(MyTest1|MyTest2*|MyTest3) does.

Metadata

Metadata

Assignees

Labels

Area: MTPBelongs to the Microsoft.Testing.Platform core library

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions