dotnet vstest: Run Built Test Assemblies
dotnet vstest runs tests from compiled test assemblies (.dll) directly, without building, using the VSTest engine that dotnet test sits on top of.
vstest is the lower-level runner. Use it when you already have built test DLLs and want to run them without a project context.
What it does
dotnet vstest takes one or more built test .dll paths and runs them through the VSTest console. Unlike dotnet test, it does not build; it expects the assemblies to exist already. Its options use PascalCase double-dash names (--TestCaseFilter, --Settings).
Common usage
dotnet vstest ./bin/Release/net8.0/Tests.dll \
--logger:"trx;LogFileName=results.trx"
dotnet vstest Tests.dll --TestCaseFilter:"Category=Smoke"
dotnet vstest Tests.dll --Settings:coverage.runsettingsOptions
| Flag | What it does |
|---|---|
| <test.dll> | One or more built test assemblies to run |
| --TestCaseFilter:<expr> | Filter tests by name, category, or trait |
| --logger:<logger> | Result logger, e.g. trx, console |
| --Settings:<file> | A .runsettings file for run configuration |
| --ResultsDirectory:<dir> | Where to write result files |
| --Parallel | Run test assemblies in parallel |
In CI
Prefer dotnet test in most pipelines; it builds and restores for you. Reach for dotnet vstest only when you build the test DLLs in one job and run them in another (artifact split), since it skips the build. Note the option syntax differs: --TestCaseFilter:"..." here vs --filter "..." on dotnet test.
Common errors in CI
"Could not find file <Tests.dll>" or "The test source file ... provided was not found" means the DLL was not built or the path is wrong; vstest never builds it for you. "No test is available" means the assembly has no discoverable tests or is missing its test adapter. Passing --filter (the dotnet test spelling) instead of --TestCaseFilter is an unrecognized argument here.