Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,20 @@ dependency already in use. Add a new dependency only at the narrowest necessary
- Do not allow unused `using` directives to be committed.
- Use `#if NET` blocks for .NET Core specific code, and `#if NETFRAMEWORK` for .NET Framework specific code.

### Target framework properties

Never hardcode a TFM (`net8.0`, `net9.0`, etc.) in a `.csproj` file. Use the appropriate
property:

| Context | Property | Defined in |
| --- | --- | --- |
| Source projects and test projects (.NET) | `$(SdkTargetFramework)` | Root `Directory.Build.props` (equals `$(NetCurrent)` from Arcade) |
| Multi-targeting with .NET Framework | Match the pattern used by peer projects in the same area. Some areas use Arcade properties (`$(NetFrameworkToolCurrent)`, `$(NetMinimum)`); others hardcode `net472`. |
| Test asset projects (`test/TestAssets/`) | `$(CurrentTargetFramework)` | Substituted at test runtime by `TestAssetsManager` via `ToolsetInfo.CurrentTargetFramework` |

## Testing

- Large changes should always include test changes.
- When creating new test projects in test/TestAssets/TestProjects, always use `$(CurrentTargetFramework)` for the `<TargetFramework>` property instead of hard-coding a specific version like `net8.0`.
- The Skip parameter of the Fact attribute to point to the specific issue link.
- To run tests in this repo (after a full build, invoke the repo-local bootstrap SDK directly):
- For MSTest-style projects: `./.dotnet/dotnet test path/to/project.csproj --filter "FullyQualifiedName~TestName"`
Expand Down
46 changes: 46 additions & 0 deletions test/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ Guidance for changes under `test/`.

## Conventions & gotchas

- **Derive from `SdkTest`** (in `Microsoft.NET.TestFramework.MSTest`). This gives you
`TestAssetsManager`, `Log` (wired to MSTest's `TestContext`), and
`BinLogArgument(...)` for binlog paths collected by Helix.
- **Use `SdkTestContext.Current` for paths** — never hardcode paths or manually discover
locations at runtime (e.g. walking up directories):

| Need | API |
| --- | --- |
| `dotnet` executable (the built SDK) | `SdkTestContext.Current.ToolsetUnderTest.DotNetHostPath` |
| Repo root (nullable in Helix) | `SdkTestContext.Current.ToolsetUnderTest.RepoRoot` or `SdkTestContext.GetRepoRoot()` |
| Test execution directory | `SdkTestContext.Current.TestExecutionDirectory` |
| Test assets root | `SdkTestContext.Current.TestAssetsDirectory` (or `TestAssetsManager` from base class) |

**Never** use `.dotnet/dotnet` or `Process.Start("dotnet", ...)` without going through
`DotNetHostPath` — this ensures the test exercises the built SDK, not a globally
installed one.
- **Test asset placement.** Put test inputs (projects, packages, workloads, etc.) in
`test/TestAssets/`. They are automatically deployed to Helix via `test/UnitTests.proj`.
- **Don't raise parallelism.** MSTest is repo-defaulted to `None` in
`test/Directory.Build.props` because of concurrency flakiness; a few projects opt
into `ClassLevel`. Cranking it up causes Helix over-subscription/timeouts.
Expand All @@ -21,3 +39,31 @@ Guidance for changes under `test/`.
them). (See `src/Cli/AGENTS.md` for the CLI-specific detail.)
- Helix work-item partitioning is driven by `test/UnitTests.proj` (per-project method
limits/multipliers) — relevant if a project's tests are unusually slow or numerous.

## Helix deployment

CI runs SDK tests on Helix machines where the repo layout differs from a local dev box.
The conventions above (SdkTest, SdkTestContext, test asset placement) handle most cases.
This section covers the additional Helix-specific concerns.

### Deploying extra files to the test execution directory

If a test needs files at runtime beyond the test assembly and test assets (scripts,
`.props`/`.targets` files, etc.), add them to `TestExecutionDirectoryFiles` in
`test/UnitTests.proj`:

```xml
<TestExecutionDirectoryFiles Include="$(RepoRoot)path\to\file.targets">
<DestinationFolder>relative/subfolder/</DestinationFolder>
</TestExecutionDirectoryFiles>
```

Files listed here are copied to `TestExecutionDirectoryFiles\` inside the Helix payload
and become available under `SdkTestContext.Current.TestExecutionDirectory`.

### Validate locally in a simulated Helix layout

Consider validating in a simulated Helix layout when your tests reference paths, use
test assets, or add new Helix payload (`TestExecutionDirectoryFiles`). See
[Repro Helix Failure](../documentation/project-docs/repro-helix-failure.md) for the
steps to create a local Helix test layout and run tests against it.
Loading