filter-syntax skill
✓ VerifiedProvides reference syntax for creating and translating test filters across VSTest and MTP for MSTest, NUnit, xUnit v3, and TUnit.
- GitHub stars
- 5,942
- Files
- 1
- Last commit
- Nov 11, 2026
- License
- MIT
- Allowed tools
- —
What does the filter-syntax skill do?
filter-syntax provides reference syntax for creating and translating test filters across VSTest and MTP for MSTest, NUnit, xUnit v3, and TUnit.
Summary generated from the skill's SKILL.md.
About the filter-syntax skill
Creating and translating test filters for .NET testing frameworks is what this skill enables. It provides a reference for developers who need to construct specific command-line expressions for VSTest or MTP environments. The tool is designed to be loaded only after a specific platform or framework has been identified, serving as a lookup for tools like run-tests and mtp-hot-reload rather than being invoked directly.
Users can access syntax rules for MSTest, NUnit, xUnit v3, and TUnit. It details how to use operators like exact matches, contains, and logical combinators such as AND and OR. The skill also provides translation logic for migrating filters from VSTest to MTP, specifically helping developers convert generic expressions into framework-specific flags like --filter-class or the path-based --treenode-filter used by TUnit.
What an agent can do with it
- 1Construct VSTest filter expressionsGenerate a command to run tests in a specific category using MSTest or NUnit.
- 2Execute complex xUnit queriesBuild a path-segment query to filter tests by assembly, namespace, and traits.
Written from the skill's SKILL.md. Every use case is checked against a quote from it.
How to install the filter-syntax skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the filter-syntax skill in Plugin
/plugin marketplace add dotnet/skills /plugin install dotnet-test@dotnet-agent-skills
Install the filter-syntax skill in Claude Code
~/.claude/skills/filter-syntax/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-test/skills/filter-syntax ~/.claude/skills/filter-syntaxInstall the filter-syntax skill in Claude Code (project)
.claude/skills/filter-syntax/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-test/skills/filter-syntax .claude/skills/filter-syntaxInstall the filter-syntax skill in Codex
~/.agents/skills/filter-syntax/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-test/skills/filter-syntax ~/.agents/skills/filter-syntaxInstall the filter-syntax skill in Gemini CLI
~/.gemini/skills/filter-syntax/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-test/skills/filter-syntax ~/.gemini/skills/filter-syntaxInstall the filter-syntax skill in Claude.ai
npx degit dotnet/skills/plugins/dotnet-test/skills/filter-syntax filter-syntax && zip -r filter-syntax.zip filter-syntax # claude.ai → Customize → Skills → + → Create skill → Upload a skill → filter-syntax.zip
Automated checks
Ran Nov 14, 2026Full report →Passed our automated checks. That is not a security audit: read the scripts before you let an agent run them. How checks work
- Source repository linked and reachabledotnet/skills/plugins/dotnet-test/skills/filter-syntax is public and reachablegithub.com/dotnet/skills/tree/HEAD/plugins/dotnet-test/skill ↗Pass
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit 2026-11-11github.com/dotnet/skills/commits ↗Pass
- No download-and-run or credential theft in scriptsNo scripts in the skill folderPass
- No hidden instructions in SKILL.mdNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/dotnet/skills/blob/HEAD/plugins/dotnet-test/skill ↗Pass
- Pre-approved tools are scopedNo pre-approved tools; the agent asks before using onegithub.com/dotnet/skills/blob/HEAD/plugins/dotnet-test/skill ↗Pass
SKILL.md
View on GitHubTest Filter Syntax Reference
Filter syntax depends on the platform and test framework.
VSTest filters (MSTest, xUnit v2, NUnit on VSTest)
dotnet test --filter <EXPRESSION>
Expression syntax: <Property><Operator><Value>[|&<Expression>]
Operators:
| Operator | Meaning |
|---|---|
= |
Exact match |
!= |
Not exact match |
~ |
Contains |
!~ |
Does not contain |
Combinators: | (OR), & (AND). Parentheses for grouping: (A|B)&C
Supported properties by framework:
| Framework | Properties |
|---|---|
| MSTest | FullyQualifiedName, Name, ClassName, Priority, TestCategory |
| xUnit | FullyQualifiedName, DisplayName, Traits |
| NUnit | FullyQualifiedName, Name, Priority, TestCategory |
An expression without an operator is treated as FullyQualifiedName~<value>.
Examples (VSTest):
# Run tests whose name contains "LoginTest"
dotnet test --filter "Name~LoginTest"
# Run a specific test class
dotnet test --filter "ClassName=MyNamespace.MyTestClass"
# Run tests in a category
dotnet test --filter "TestCategory=Integration"
# Exclude a category
dotnet test --filter "TestCategory!=Slow"
# Combine: class AND category
dotnet test --filter "ClassName=MyNamespace.MyTestClass&TestCategory=Unit"
# Either of two classes
dotnet test --filter "ClassName=MyNamespace.ClassA|ClassName=MyNamespace.ClassB"
MTP filters — MSTest and NUnit
MSTest and NUnit on MTP use the same --filter syntax as VSTest (same properties, operators, and combinators). The only difference is how the flag is passed:
# .NET SDK 8/9 (after --)
dotnet test -- --filter "Name~LoginTest"
# .NET SDK 10+ (direct)
dotnet test --filter "Name~LoginTest"
MTP filters — xUnit (v3)
xUnit v3 on MTP uses framework-specific filter flags instead of the generic --filter expression:
| Flag | Description |
|---|---|
--filter-class "name" |
Run all tests in a given class |
--filter-not-class "name" |
Exclude all tests in a given class |
--filter-method "name" |
Run a specific test method |
--filter-not-method "name" |
Exclude a specific test method |
--filter-namespace "name" |
Run all tests in a namespace |
--filter-not-namespace "name" |
Exclude all tests in a namespace |
--filter-trait "name=value" |
Run tests with a matching trait |
--filter-not-trait "name=value" |
Exclude tests with a matching trait |
Multiple values can be specified with a single flag: --filter-class Foo Bar.
# .NET SDK 8/9
dotnet test -- --filter-class "MyNamespace.LoginTests"
# .NET SDK 10+
dotnet test --filter-class "MyNamespace.LoginTests"
# Combine: namespace + trait
dotnet test --filter-namespace "MyApp.Tests.Integration" --filter-trait "Category=Smoke"
xUnit v3 query filter language
For complex expressions, use --filter-query with a path-segment syntax:
/<assemblyFilter>/<namespaceFilter>/<classFilter>/<methodFilter>[traitName=traitValue]
Each segment matches against: assembly name, namespace, class name, method name. Use * for "match all" in any segment. Documentation: https://xunit.net/docs/query-filter-language
# xUnit.net v3 MTP — using query language (assembly/namespace/class/method[trait])
dotnet test -- --filter-query "/*/*/*IntegrationTests*/*[Category=Smoke]"
MTP filters — TUnit
TUnit uses --treenode-filter with a path-based syntax:
--treenode-filter "/<Assembly>/<Namespace>/<ClassName>/<TestName>"
Wildcards (*) are supported in any segment. Filter operators can be appended to test names for property-based filtering.
| Operator | Meaning |
|---|---|
* |
Wildcard match |
= |
Exact property match (e.g., [Category=Unit]) |
!= |
Exclude property value |
& |
AND (combine conditions) |
| |
OR (within a segment, requires parentheses) |
Examples (TUnit):
# All tests in a class
dotnet run --treenode-filter "/*/*/LoginTests/*"
# A specific test
dotnet run --treenode-filter "/*/*/*/AcceptCookiesTest"
# By namespace prefix (wildcard)
dotnet run --treenode-filter "/*/MyProject.Tests.Api*/*/*"
# By custom property
dotnet run --treenode-filter "/*/*/*/*[Category=Smoke]"
# Exclude by property
dotnet run --treenode-filter "/*/*/*/*[Category!=Slow]"
# OR across classes
dotnet run --treenode-filter "/*/*/(LoginTests)|(SignupTests)/*"
# Combined: namespace + property
dotnet run --treenode-filter "/*/MyProject.Tests.Integration/*/*/*[Priority=Critical]"
VSTest → MTP filter translation (for migration)
MSTest, NUnit, and xUnit.net v2 (with YTest.MTP.XUnit2): The VSTest --filter syntax is identical on both VSTest and MTP. No changes needed.
xUnit.net v3 (native MTP): xUnit.net v3 does NOT support the VSTest --filter syntax on MTP. Translate filters using xUnit.net v3's native options:
VSTest --filter syntax |
xUnit.net v3 MTP equivalent | Notes |
|---|---|---|
FullyQualifiedName~ClassName |
--filter-class *ClassName* |
Wildcards required for substring match |
FullyQualifiedName=Ns.Class.Method |
--filter-method Ns.Class.Method |
Exact match on fully qualified method |
Name=MethodName |
--filter-method *MethodName* |
Wildcards for substring match |
Category=Value (trait) |
--filter-trait "Category=Value" |
Filter by trait name/value pair |
| Complex expressions | --filter-query "expr" |
Uses xUnit.net query filter language (see above) |
Files in this skill
1filter-syntax skill questions
How do I install the filter-syntax skill in Claude Code?
Run npx degit dotnet/skills/plugins/dotnet-test/skills/filter-syntax ~/.claude/skills/filter-syntax. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the filter-syntax skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.
How do I run tests in a specific category using VSTest?
You can use the TestCategory property with an exact match operator, for example: dotnet test --filter "TestCategory=Integration".
Does xUnit v3 on MTP support the standard VSTest filter syntax?
No, xUnit v3 on MTP does not support the standard VSTest --filter syntax and requires using framework-specific flags or the --filter-query option.
What is the syntax for TUnit tree node filtering?
TUnit uses a path-based syntax: --treenode-filter "/<Assembly>/<Namespace>/<ClassName>/<TestName>" and supports wildcards.