# Filter Syntax for MSTest, xUnit v3, and TUnit on Microsoft Testing Platform (MTP)

> Master filter syntax for MSTest, xUnit v3, and TUnit on Microsoft Testing Platform. Learn how to precisely target tests for efficient execution and debugging.

- Repository: [.NET Platform/skills](https://github.com/dotnet/skills)
- Tags: tutorial
- Published: 2026-07-11

---

**MSTest uses VSTest-style `--filter` expressions, xUnit v3 requires framework-specific flags like `--filter-class` or `--filter-query`, and TUnit relies on `--treenode-filter` with path-based wildcards when running on the Microsoft Testing Platform.**

The `dotnet/skills` repository defines how test filtering works across different frameworks on the Microsoft Testing Platform (MTP). While MSTest, xUnit v3, and TUnit all execute on the same underlying platform, each framework exposes its own distinct syntax for selecting specific tests at run-time.

## MSTest and NUnit: VSTest-Style Filtering

When running **MSTest** or **NUnit** on MTP, you use the classic VSTest filter syntax documented in [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md). This syntax combines **properties**, **operators**, and **combinators** to target specific tests.

Supported properties include `FullyQualifiedName`, `Name`, `ClassName`, `Priority`, and `TestCategory`. Valid operators are `=` (equals), `!=` (not equals), `~` (contains), and `!~` (does not contain). Use `|` for OR and `&` for AND to build complex expressions.

The command structure differs slightly based on your SDK version:

- **SDK 8/9**: Pass the filter after a double-dash separator: `dotnet test -- --filter "<expression>"`
- **SDK 10+**: Use the standard syntax directly: `dotnet test --filter "<expression>"`

```bash

# SDK 10+ - Run integration tests only

dotnet test --filter "TestCategory=Integration"

# SDK 8/9 - Same filter with extra --

dotnet test -- --filter "TestCategory=Integration"

# Complex filter - High priority OR specific class

dotnet test --filter "Priority=1 | ClassName=MyNamespace.AuthTests"

```

## xUnit v3: Framework-Specific Flags

**xUnit v3** on MTP deliberately does **not** reuse the VSTest `--filter` syntax. Instead, it implements its own set of command-line flags defined in the xUnit-specific sections of [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md):

- `--filter-class "name"` – Run all tests within a specific class
- `--filter-method "name"` – Run a specific test method
- `--filter-trait "name=value"` – Run tests matching a specific trait key-value pair
- `--filter-query "path-syntax"` – Execute complex queries using xUnit's query-filter language

The **query-filter language** uses a hierarchical path structure: `/assembly/namespace/class/method[trait=value]`. You can substitute any segment with the `*` wildcard to match multiple values.

```bash

# Run all tests in the LoginTests class

dotnet test --filter-class "MyNamespace.LoginTests"

# Run tests with Smoke category trait

dotnet test --filter-trait "Category=Smoke"

# Complex query - Any assembly, any namespace, classes containing "Integration", with Smoke trait

dotnet test --filter-query "/*/*/*IntegrationTests*/*[Category=Smoke]"

```

## TUnit: Tree-Node Path Filtering

**TUnit** employs a fundamentally different approach using the `--treenode-filter` flag. According to the TUnit specifications in [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md), this filter accepts a path of the form `/Assembly/Namespace/ClassName/TestName`.

Wildcards (`*`) can replace any path segment. Additionally, you can append property operators (`=`, `!=`, `&`, `|`) directly to test names for trait-based filtering.

```bash

# Run a specific test by full path

dotnet run --treenode-filter "/MyAssembly/Tests/AuthServiceTest/ValidateToken"

# Run all tests in any class named *Test using wildcards

dotnet run --treenode-filter "/*/*/AcceptCookiesTest"

```

## Platform Detection and Command Construction

The `run-tests` skill does not require you to manually memorize these syntax differences. Instead, it relies on [`platform-detection/SKILL.md`](https://github.com/dotnet/skills/blob/main/platform-detection/SKILL.md) to analyze your project files and determine whether you are using VSTest or MTP, and which specific framework (MSTest, xUnit v3, or TUnit) is referenced.

Based on this detection, the `run-tests` skill automatically selects the appropriate filter syntax from the reference data in [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md) and constructs the correct command line. The skill files themselves are **reference data only**—they are loaded dynamically and should not be invoked directly.

Additional framework-specific attributes (such as `[TestCategory]` for MSTest) are documented in [`test-analysis-extensions/dotnet.md`](https://github.com/dotnet/skills/blob/main/test-analysis-extensions/dotnet.md), which informs the filter validation logic.

## Summary

- **MSTest/NUnit**: Use **VSTest-style** `--filter` expressions on MTP, with an extra `--` separator required for SDK 8/9 but not for SDK 10+.
- **xUnit v3**: Use **framework-specific flags** (`--filter-class`, `--filter-method`, `--filter-trait`) or the **query-filter** path language rather than the standard `--filter` syntax.
- **TUnit**: Use the **tree-node filter** (`--treenode-filter`) with slash-delimited paths and wildcard support.
- The `dotnet/skills` repository stores these definitions in [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md), consumed automatically by the `run-tests` and `platform-detection` skills to generate correct commands.

## Frequently Asked Questions

### Why does xUnit v3 use different filter syntax than MSTest on MTP?

xUnit v3 implements its own filtering mechanism to provide more granular control over test selection. According to the [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md) file, xUnit v3 treats filtering as a first-class framework feature rather than delegating to the underlying platform's generic filter engine, which is why it exposes specific flags like `--filter-class` and `--filter-query` instead of the standard `--filter` expression.

### How do I filter TUnit tests by trait value?

You can append property operators directly to the test name in the `--treenode-filter` path. For example, use `--treenode-filter "/*/*/MyClass/TestName[Category=Smoke]"` to filter by traits. The path-based syntax supports standard operators (`=`, `!=`) and logical combinators (`&`, `|`) appended to the test name segment, as documented in the TUnit sections of [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md).

### What changed in .NET SDK 10+ for MSTest filtering?

In SDK 8/9, when using MTP with MSTest, you had to pass the `--filter` argument after a double-dash separator (`dotnet test -- --filter "..."`) to ensure the argument was forwarded correctly. SDK 10+ streamlined this to match the VSTest experience, allowing `dotnet test --filter "..."` directly without the extra `--` separator. The underlying syntax and operators remain identical.

### Where are the filter syntax rules defined in the dotnet/skills repository?

The master reference resides in [`filter-syntax/SKILL.md`](https://github.com/dotnet/skills/blob/main/filter-syntax/SKILL.md), which documents VSTest, MTP, xUnit v3, and TUnit filter syntaxes. Framework-specific test attributes used during filter analysis are listed in [`test-analysis-extensions/dotnet.md`](https://github.com/dotnet/skills/blob/main/test-analysis-extensions/dotnet.md). Detection logic for determining which syntax to apply is implemented in [`platform-detection/SKILL.md`](https://github.com/dotnet/skills/blob/main/platform-detection/SKILL.md), while [`run-tests/SKILL.md`](https://github.com/dotnet/skills/blob/main/run-tests/SKILL.md) orchestrates the actual execution by consuming these reference files.