Install any skill in seconds. Free to start, no credit card required.
Get Started Free →How to build and test .NET projects in the Agent Framework repository. Use this when verifying or testing changes.
.claude/skills/microsoft-build-and-test/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 155% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 101% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 112% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 119% | 0% |
../project-structure/SKILL.md for project structure details.bash# From dotnet/ directory dotnet restore --tl:off # Restore dependencies for all projects dotnet build --tl:off # Build all projects dotnet test # Run all tests dotnet format # Auto-fix formatting for all projects # Build/test/format a specific project (preferred for isolated/internal changes) dotnet build src/Microsoft.Agents.AI.<Package> --tl:off dotnet test --project tests/Microsoft.Agents.AI.<Package>.UnitTests dotnet format src/Microsoft.Agents.AI.<Package> # Run a single test # Replace the filter values with the appropriate assembly, namespace, class, and method names for the test you want to run and use * as a wildcard elsewhere, e.g. "/*/*/HttpClientTests/GetAsync_ReturnsSuccessStatusCode" # Use `--ignore-exit-code 8` to avoid failing the build when no tests are found for some projects dotnet test --filter-query "/<assemblyFilter>/<namespaceFilter>/<classFilter>/<methodFilter>" --ignore-exit-code 8 # Run unit tests only # Use `--ignore-exit-code 8` to avoid failing the build when no tests are found for integration test projects dotnet test --filter-query "/*UnitTests*/*/*/*" --ignore-exit-code 8
Use --tl:off when building to avoid flickering when running commands in the agent.
The full solution is large. Use these shortcuts:
| Change type | What to do | |-------------|------------| | Isolated/Internal logic | Build only the affected project and its *.UnitTests project. Fix issues, then build the full solution and run all unit tests. | | Public API surface | Build the full solution and run all unit tests immediately. |
Example: Building a single code project for all target frameworks
bash# From dotnet/ directory dotnet build ./src/Microsoft.Agents.AI.Abstractions
Example: Building a single code project for just .NET 10.
bash# From dotnet/ directory dotnet build ./src/Microsoft.Agents.AI.Abstractions -f net10.0
Example: Running tests for a single project using .NET 10.
bash# From dotnet/ directory dotnet test --project ./tests/Microsoft.Agents.AI.Abstractions.UnitTests -f net10.0
Example: Running a single test in a specific project using .NET 10. Provide the full namespace, class name, and method name for the test you want to run:
bash# From dotnet/ directory dotnet test --project ./tests/Microsoft.Agents.AI.Abstractions.UnitTests -f net10.0 --filter-query "/*/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunOptionsTests/CloningConstructorCopiesProperties"
Most projects target multiple .NET frameworks. If the affected code does not use #if directives for framework-specific logic, pass -f net10.0 to speed up building and testing.
dotnet build will try and restore packages for all projects on each build, which can be slow. Unless packages have been changed, or it's the first time building the solution, add --no-restore to the build command to skip this step and speed up builds.
Just remember to run dotnet restore after pulling changes, making changes to project references, or when building for the first time.
Unit tests target both .NET Framework as well as .NET Core. When running on Linux, only the .NET Core tests can be run, as .NET Framework is not supported on Linux.
To run only the .NET Core tests, use the -f net10.0 option with dotnet test.
Tests use the Microsoft Testing Platform via xUnit v3. Key differences from the legacy VSTest runner:
dotnet test requires --project to specify a test project directly (positional arguments are no longer supported).[✓112/x0/↓0] progress and Test run summary: Passed!).--report-xunit-trx instead of --logger trx.Microsoft.Testing.Extensions.CodeCoverage with --coverage --coverage-output-format cobertura.dotnet run --project <test-project>. This bypasses the dotnet test infrastructure and runs the test executable directly with the MTP command line.--ignore-exit-code 8 to suppress this:bash# Run all unit tests across the solution, ignoring projects with no matching tests dotnet test --solution ./agent-framework-dotnet.slnx --no-build -f net10.0 --ignore-exit-code 8
--solution for a specific TFM requires all projects in the solution to support that TFM. Not all projects target every framework (e.g., some are net10.0-only). Use ./dotnet/eng/scripts/New-FilteredSolution.ps1 to generate a filtered solution:powershell# Generate a filtered solution for net472 and run tests $filtered = ./dotnet/eng/scripts/New-FilteredSolution.ps1 -Solution dotnet/agent-framework-dotnet.slnx -TargetFramework net472 dotnet test --solution $filtered --no-build -f net472 --ignore-exit-code 8 # Exclude samples and keep only unit test projects ./dotnet/eng/scripts/New-FilteredSolution.ps1 -Solution dotnet/agent-framework-dotnet.slnx -TargetFramework net10.0 -ExcludeSamples -TestProjectNameFilter "*UnitTests*" -OutputPath dotnet/filtered-unit.slnx
bash# Run tests via dotnet test (uses MTP under the hood) dotnet test --project ./tests/Microsoft.Agents.AI.UnitTests -f net10.0 # Run tests with code coverage (Cobertura format) dotnet test --project ./tests/Microsoft.Agents.AI.UnitTests -f net10.0 --coverage --coverage-output-format cobertura --coverage-settings ./tests/coverage.runsettings # Run tests directly via dotnet run (MTP native command line) dotnet run --project ./tests/Microsoft.Agents.AI.UnitTests -f net10.0 # Show MTP command line help dotnet run --project ./tests/Microsoft.Agents.AI.UnitTests -f net10.0 -- -?
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 6,442 | 2,928 | -55% | 1 | 1 | 0% | 973 | 1,985 | +104% | 0 | 0 | — |
case-02 | fail→pass | 4,552 | 3,544 | -22% | 1 | 1 | 0% | 886 | 2,257 | +155% | 0 | 0 | — |
case-03 | fail→pass | 9,541 | 5,528 | -42% | 1 | 1 | 0% | 1,434 | 2,569 | +79% | 0 | 0 | — |
case-04 | pass→pass | 7,842 | 3,144 | -60% | 1 | 1 | 0% | 1,378 | 2,134 | +55% | 0 | 0 | — |
case-05 | pass→pass | 2,558 | 1,449 | -43% | 1 | 1 | 0% | 420 | 1,859 | +343% | 0 | 0 | — |
case-06 | pass→pass | 9,598 | 5,894 | -39% | 1 | 1 | 0% | 1,636 | 2,575 | +57% | 0 | 0 | — |
case-07 | fail→pass | 6,603 | 2,505 | -62% | 1 | 1 | 0% | 958 | 1,922 | +101% | 0 | 0 | — |
case-08 | fail→pass | 15,977 | 3,202 | -80% | 1 | 1 | 0% | 1,070 | 2,269 | +112% | 0 | 0 | — |
case-09 | fail→fail | 6,751 | 3,121 | -54% | 1 | 1 | 0% | 1,256 | 2,259 | +80% | 0 | 0 | — |
case-10 | fail→pass | 5,091 | 2,686 | -47% | 1 | 1 | 0% | 952 | 2,081 | +119% | 0 | 0 | — |
case-11 | fail→pass | 14,046 | 3,175 | -77% | 1 | 1 | 0% | 2,669 | 2,224 | -17% | 0 | 0 | — |
case-12 | fail→pass | 13,119 | 3,407 | -74% | 1 | 1 | 0% | 2,540 | 2,325 | -8% | 0 | 0 | — |
case-13 | pass→pass | 13,700 | 5,680 | -59% | 1 | 1 | 0% | 2,203 | 2,690 | +22% | 0 | 0 | — |
case-14 | fail→pass | 12,888 | 6,491 | -50% | 1 | 1 | 0% | 2,086 | 2,703 | +30% | 0 | 0 | — |
case-15 | fail→pass | 22,740 | 1,886 | -92% | 1 | 1 | 0% | 4,125 | 1,997 | -52% | 0 | 0 | — |
case-16 | pass→pass | 7,445 | 2,236 | -70% | 1 | 1 | 0% | 1,176 | 1,958 | +66% | 0 | 0 | — |
case-17 | pass→pass | 5,553 | 2,172 | -61% | 1 | 1 | 0% | 961 | 1,950 | +103% | 0 | 0 | — |
case-18 | fail→pass | 6,703 | 3,797 | -43% | 1 | 1 | 0% | 1,218 | 2,290 | +88% | 0 | 0 | — |
case-19 | fail→fail | 4,799 | 3,066 | -36% | 1 | 1 | 0% | 892 | 2,149 | +141% | 0 | 0 | — |
case-20 | fail→fail | 16,247 | 6,636 | -59% | 1 | 1 | 0% | 2,503 | 1,901 | -24% | 0 | 0 | — |
case-21 | pass→pass | 6,363 | 12,086 | +90% | 1 | 1 | 0% | 937 | 4,145 | +342% | 0 | 0 | — |
case-22 | pass→pass | 6,275 | 6,191 | -1% | 1 | 1 | 0% | 1,159 | 2,706 | +133% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 20 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.