Environments
The environment names the overlay: staging loads precept.staging.json, and Precept.TestData loads testdata.staging.json beside every data file. It is resolved once per run, first of these to say anything:
| Source | For | |
|---|---|---|
| 1 | --precept-environment staging |
CI, and anything driven from a shell |
| 2 | PRECEPT_ENVIRONMENT |
a build agent, a container |
| 3 | DOTNET_ENVIRONMENT |
a suite that already sets it |
| 4 | the build configuration | switching environments in an IDE |
| 5 | "Environment" in precept.json |
the team's default |
| 6 | — | local |
An "Environment" key in an overlay does nothing: the overlay is chosen before it is read.
dotnet run --project Checkout.Tests -- --precept-environment staging
dotnet test --project Checkout.Tests/Checkout.Tests.csproj -- --precept-environment staging
Every run says which environment it used, and complains when the overlay for it is not there — the case where a typo quietly runs the suite against the defaults:
[Precept] Environment 'staging'. Filter excluded 5 of 33 tests.
[Precept] There is no 'precept.nope.json' beside the test binary, so the run is using 'precept.json' alone.
Switching environments from an IDE#
Neither Visual Studio's Test Explorer nor VS Code's testing pane has anywhere to type a runner argument, and editing a committed file to switch leaves you with a modified working tree to remember not to push. Make each environment a build configuration instead — the IDE already has a picker for those.
Declare them once, in the test project or in Directory.Build.props:
<PropertyGroup>
<Configurations>Debug;Release;Dev;Stage</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Dev'">
<PreceptEnvironment>dev</PreceptEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Stage'">
<PreceptEnvironment>stage</PreceptEnvironment>
</PropertyGroup>
That is the whole consumer side. Precept.TestPlatform carries PreceptEnvironment into runtimeconfig.json as a Precept.Environment property, and Precept reads it back at startup. Pick Stage from the configuration list and Test Explorer runs against Stage; pick Dev and it runs against Dev. Nothing to edit, nothing to leave modified, nothing to push by accident — the selected configuration is IDE state, not a file in your repository. From a shell it is dotnet test -c Stage.
Each configuration builds to its own bin/Stage/, so switching costs a rebuild, and the two never overwrite each other's output. Add the configurations to the solution too (Visual Studio: Build → Configuration Manager) so the picker offers them.
An environment variable or --precept-environment still overrides the build, which is what keeps CI in charge of its own runs.
.runsettingsdoes not work here. It is a VSTest concept, and Precept is a Microsoft.Testing.Platform framework with no VSTest bridge:dotnet test --settings …runs zero tests and exits 5. The platform has no--settingsoption at all. Its replacement istestconfig.jsonin the project directory, which sets any runner option and is copied to the output as{AssemblyName}.testconfig.jsonbyMicrosoft.Testing.Platform.MSBuild:{ "commandLineOptions": { "precept-environment": "stage" } }Reach for it over a build configuration only when you want one machine's override without touching the project file — it outranks
precept.json, so gitignore it if that is what you are using it for.
To run against two environments at once — a smoke pack against staging while a regression pack runs locally — use two shells rather than one IDE:
dotnet run --project Checkout.Tests -- --precept-environment staging --precept-filter "smoke" &
dotnet run --project Checkout.Tests -- --precept-environment local --precept-filter "not smoke"