Code Testing Extensions
.NET (Microsoft)OfficialPublished by .NET (Microsoft)
- Skill
- Guidelines
- Software development
- MIT
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Code Testing Extensions is a non-invocable reference library designed to support automated testing workflows. It provides a structured collection of documentation files covering various programming languages, including .NET, Python, TypeScript, Go, Java, and more. Each entry offers essential guidance on build and test commands, framework-specific patterns, mocking strategies, and common error resolution. Additionally, the catalog includes example files that demonstrate complete testing pipeline cycles, from research and planning to test generation and reporting.
What it does
- Provides language-specific testing guidance for multiple programming environments.
- Lists standard build and test commands for various testing frameworks.
- Offers best practices for mocking, project layout, and framework detection.
- Includes concrete examples of full testing pipeline workflows.
- Serves as a centralized reference for agents to ensure consistent testing standards.
When to use it
- When an agent needs to determine the correct testing commands for a specific language.
- When implementing or debugging a testing pipeline for a new project.
- When guidance on framework-specific mocking or test structure is required.
- When looking for representative examples of a complete test generation cycle.
Advantages
- Ensures consistency across different testing environments.
- Reduces ambiguity by providing standardized commands and patterns.
- Provides both high-level guidance and concrete implementation examples.
- Supports a wide range of modern programming languages and frameworks.
Usage examples
- “Read extensions/python.md to understand the preferred testing patterns for a pytest project.”
- The agent retrieves the Python-specific guidance, identifying the correct test runner commands and mocking strategies to apply.
- “Consult extensions/java-examples.md to see how to structure a JUnit 5 test suite.”
- The agent reviews the provided example to replicate the established project structure and testing conventions for the Java codebase.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/dotnet/code-testing-extensions/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip code-testing-extensions.zip -d .agents/skills
Documentation by .NET (Microsoft)
Code Testing Extensions
This reference-only catalog lists bundled guidance for the code-testing pipeline. Read the matching file directly; do not invoke this catalog as a skill. Resource paths are relative to this catalog, not the project workspace.
Available Extension Files
| File | Language | Contents |
|---|---|---|
| extensions/dotnet.md | .NET (C#/F#/VB) | Build commands, test commands, project reference validation, common CS error codes, MSTest template |
| extensions/python.md | Python | Framework-adaptive test commands (pytest, custom runners), project layout detection, mocking guidelines, common errors |
| extensions/typescript.md | TypeScript/JavaScript | Build/test commands (Jest/Vitest/Mocha), framework detection, mocking, TS-specific considerations |
| extensions/powershell.md | PowerShell | Test commands (Pester v5), module import patterns, discovery/run pitfalls, mocking, common errors |
| extensions/cpp.md | C++ | Testing internals with friend declarations |
| extensions/go.md | Go | go test commands, table-driven tests, integration vs unit layout, mocking via interfaces, common errors |
| extensions/java.md | Java | Maven/Gradle commands, JUnit 4/5 and TestNG detection, Mockito, Spring Boot slices, common errors |
| extensions/rust.md | Rust | cargo test commands, unit vs integration vs doc tests, features, async test harnesses, common errors |
| extensions/ruby.md | Ruby | RSpec and Minitest commands, Bundler usage, Rails specifics, mocking patterns, common errors |
| extensions/swift.md | Swift | SPM and Xcode test commands, XCTest vs Swift Testing, @testable import, async/throws tests, common errors |
| extensions/kotlin.md | Kotlin | Gradle commands, JUnit/Kotest detection, MockK, coroutines test, KMP and Android specifics, common errors |
| extensions/dotnet-examples.md | .NET (C#/F#/VB) | Concrete pipeline examples: sample research output, plan, generated tests, fix cycles, final report |
| extensions/python-examples.md | Python | Concrete pipeline examples (pytest): research, plan, generated test file, fix cycles, final report |
| extensions/typescript-examples.md | TypeScript/JavaScript | Concrete pipeline examples (Vitest, applicable to Jest): research, plan, generated test file, fix cycles, final report |
| extensions/go-examples.md | Go | Concrete pipeline examples (standard testing): research, plan, table-driven test file, fix cycles, final report |
| extensions/java-examples.md | Java | Concrete pipeline examples (JUnit 5 + Mockito on Maven): research, plan, generated test file, fix cycles, final report |
Usage
Read the appropriate base extension before writing test code. Load an
<language>-examples.md file only when the repository has no representative
tests and the base extension does not resolve the needed pattern. Do not load
end-to-end examples for a focused request with established local conventions.
Files
- ATTRIBUTION.mdAdded by AutoGineer857 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md3.7 KiB
- extensions/cpp-examples.md9.1 KiB
- extensions/cpp.md20.1 KiB
- extensions/dotnet-examples.md10.7 KiB
- extensions/dotnet.md10.5 KiB
- extensions/go-examples.md12.4 KiB
- extensions/go.md7.8 KiB
- extensions/java-examples.md11.9 KiB
- extensions/java.md9.7 KiB
- extensions/kotlin-examples.md10.3 KiB
- extensions/kotlin.md11.2 KiB
- extensions/powershell-examples.md9.1 KiB
- extensions/powershell.md12.1 KiB
- extensions/python-examples.md12.1 KiB
- extensions/python.md11.7 KiB
- extensions/ruby-examples.md8.9 KiB
- extensions/ruby.md14.7 KiB
- extensions/rust-examples.md10.6 KiB
- extensions/rust.md8.8 KiB
- extensions/swift.md9.4 KiB
- extensions/typescript-examples.md12.7 KiB
- extensions/typescript.md7.9 KiB
extensions/powershell.md
PowerShell Extension
Language-specific guidance for PowerShell test generation using Pester v5.
Rule #0: Confirm the Test Target
If the prompt does not name a specific file (e.g. "test the repository", "cover one core module", "comprehensive suite"), do not assume the largest or top-level upstream code is the intended target. In real workflows the user usually wants to test code they have just added, and large upstream repos contain hundreds of scripts already covered by existing *.Tests.ps1 files.
Run these read-only discovery commands first — they are the deliberate exception to Rule #1's "before writing any test or running any command" rule, and their output is the ground truth Rule #1's reading is meant to interpret. Do not write or execute any tests until Rule #0 and Rule #1 are both complete.
| Goal | Command |
|---|---|
| List uncommitted edits + untracked files | git status -s |
| Untracked files only (typical for newly-added modules) | git ls-files --others --exclude-standard |
| Recently added scripts/modules | git log --diff-filter=A --name-only -5 -- '*.ps1' '*.psm1' '*.psd1' |
Modules with no matching *.Tests.ps1 | compare Get-ChildItem -Recurse -Include *.psm1,*.ps1 against *.Tests.ps1 files |
Prefer targets that match all of:
Untracked or recently added (
git status/git log --diff-filter=A).Small and pure (a few hundred lines, no external state, no
Invoke-WebRequest/registry/filesystem side effects).Located under a conventional source root (
tools/,src/,Public/,Private/, or the module root next to a.psd1).Have no existing matching
*.Tests.ps1file.
If a .psd1 manifest's RootModule (or ModuleToProcess) points at a specific .psm1, that module is almost certainly the target — start there.
Test Placement Contract
Pester only discovers tests under the path passed to Invoke-Pester -Path (or the current directory when no path is given). Verification harnesses (CI, msbench, coverage tools) typically scope discovery to a single directory such as tools/ or tests/. Place every test file there, matching the existing convention in the repo:
| Layout used by the repo | Test placement |
|---|---|
Co-located convention (Module.psm1 + Module.Tests.ps1 side-by-side) | Drop <Module>.Tests.ps1 next to the source file (tools/StringUtils.psm1 → tools/StringUtils.Tests.ps1). |
Sibling Tests/ directory | Mirror the source path (src/Foo/Bar.psm1 → Tests/Foo/Bar.Tests.ps1). |
| Mixed / unknown | Co-locate next to the source — this is what Pester discovers by default and what most harnesses scope to. |
A *.Tests.ps1 file placed outside the discovery root will be invisible to both Invoke-Pester and the harness.
First-Test Sanity Loop
After writing the first *.Tests.ps1 file — before writing any others:
Run
Invoke-Pester -Path <dir> -PassThruand confirm theTotalCountis> 0. If it is0, Pester is not discovering your file; fix the location, filename, orDescribe/Itstructure before continuing.Run the test (
Invoke-Pester -Path <your.Tests.ps1> -Output Detailed); fixImport-Module/ dot-source /BeforeAllerrors before adding more tests.Only then expand to cover the remaining functions.
This catches placement and discovery mistakes on turn 1 instead of after dozens of failed-test iterations.
Harness Discovery Check
Before reporting success, run the harness-equivalent discovery command from the repo root and confirm the test count went up by at least the number of tests you generated. CI/msbench/coverage harnesses do not know which directory you targeted with -Path; they invoke Pester from the repo root with default discovery, so a test that passes via Invoke-Pester -Path ./tools/Foo.Tests.ps1 is still worthless if Invoke-Pester from the repo root does not enumerate it.
# From repo root — mirrors what a generic harness sees
$result = Invoke-Pester -Configuration @{ Run = @{ PassThru = $true; SkipRun = $true } }
"$($result.TotalCount) tests discovered"If the count did not increase, your *.Tests.ps1 file is outside the harness discovery root. Move it to the convention the repo's existing tests use (or, if there are no existing tests, prefer the repo root's tests/, Tests/, tst/, test/, or co-locate next to the source). Do not report success until the harness-equivalent command sees your new tests.
Rule #1: Investigate the Repo First
Before writing any test or running any command, read:
Existing tests — find
*.Tests.ps1files and copy their style (structure, assertions, mock approach, import method)Module structure — look for
.psd1(manifest),.psm1(root module),Public//Private/organizationBuild/test scripts — check for
build.ps1,Invoke-Build(*.build.ps1),psake, or CI scriptsShell target — check
.psd1forPowerShellVersion/CompatiblePSEditions, CI matrix forpwshvspowershell.exe
Use the repo's existing test conventions. Only add Pester if the repo has no tests at all.
Build Commands
PowerShell is interpreted — no build step. If the repo has a build script, use it. Otherwise validate with:
Module loads:
Import-Module ./MyModule.psd1 -Force -ErrorAction StopScript analyzer:
Invoke-ScriptAnalyzer -Path ./src -Recurse(if PSScriptAnalyzer is available)Lint:
Invoke-ScriptAnalyzer -Path path/to/file.ps1 -Fix
Test Commands
| Scope | Command |
|---|---|
| All tests | Invoke-Pester |
| Specific file | Invoke-Pester -Path ./Tests/Get-Widget.Tests.ps1 |
| Filter by name | Invoke-Pester -FullNameFilter '*Get-Widget*' |
| Filter by tag | Invoke-Pester -TagFilter 'Unit' |
| Non-interactive (CI) | Invoke-Pester -CI |
| Detailed output | Invoke-Pester -Output Detailed |
Prefer the repo's build/test script over raw
Invoke-PesterUse
-Output Detailedduring fix cycles,-Output Minimalfor final validation
Project Layout and Imports
| Layout | Import in BeforeAll |
|---|---|
Module (.psd1) | Import-Module "$PSScriptRoot/../MyModule.psd1" -Force |
| Library script (defines functions) | . $PSScriptRoot/Get-Widget.ps1 |
| Co-located test | . $PSCommandPath.Replace('.Tests.ps1', '.ps1') |
Executable script (has param()) | Do not dot-source — invoke with & $PSScriptRoot/script.ps1 -Param value and assert on output/errors |
All imports go in
BeforeAll— never at script top levelUse
$PSScriptRootor$PSCommandPath— never$MyInvocation.MyCommand.Path(returns empty inBeforeAll)Use
-ForceonImport-Moduleto pick up changes between runs
Test File Naming
Files:
*.Tests.ps1— match existing convention (co-located vsTests/directory)
Pester v5 Discovery vs Run (Critical)
Pester v5 runs in two phases: Discovery (collects test metadata) then Run (executes tests). This is the #1 source of agent errors.
Rules:
All setup code goes in
BeforeAllorBeforeEach— never at script top level or loose insideDescribe/ContextCode directly inside
Describe/Context(but outsideIt/Before*/After*) runs during Discovery — do not put setup, imports, or variable assignments thereData for
-ForEach/-TestCasesmust be set inBeforeDiscovery, notBeforeAll(BeforeAll runs after discovery)-Skip:$conditionevaluates at Discovery time — conditions fromBeforeAllwill be$nullUse
foreachloops for dynamic test generation only withBeforeDiscoverydataUse
TestDrive:for file-based tests instead of touching repo files — Pester cleans it up automatically
Parameterized Test Display Names
Apply Report-safe test names and result validation.
Use an explicit safe Name/Case in -ForEach or -TestCases data and expand
only that field in the It title. Do not expand arbitrary <Input> or
<Expected> values into discovery/report metadata.
For a function whose contract reverses UTF-16 code units (not Unicode scalars), the reversed supplementary character is intentionally malformed UTF-16. Keep that expected value in the assertion, not the title:
Use Text for the data field, not Input: $Input is PowerShell's automatic
pipeline-input variable and can hide the intended case value inside It.
BeforeDiscovery {
$cases = @(
@{
Name = 'supplementary code-unit reversal'
Text = [string]::Concat([char]0xD83D, [char]0xDE00)
Expected = [string]::Concat([char]0xDE00, [char]0xD83D)
}
@{
Name = 'isolated high surrogate'
Text = [string][char]0xD800
Expected = [string][char]0xD800
}
)
}
Describe 'Get-Reversed' {
BeforeAll {
Import-Module (Join-Path $PSScriptRoot '../tools/StringUtils.psm1') -Force
}
It 'reverses <Name>' -ForEach $cases {
Get-Reversed -Value $Text | Should -BeExactly $Expected
}
}Reuse the repository's configured Pester TestResult export path and format
when present and parse the resulting artifact before reporting success. A
passing TotalCount/PassedCount does not prove JUnit export succeeded.
Common Errors
| Error | Fix |
|---|---|
Variable is $null in It block | Move assignment into BeforeAll — variables set there are visible to child It blocks without $script: |
-ForEach data is empty | Move data setup from BeforeAll to BeforeDiscovery |
CommandNotFoundException for Mock target | The function must exist before mocking — import the module in BeforeAll first |
$MyInvocation.MyCommand.Path returns empty | Use $PSCommandPath or $PSScriptRoot instead |
Should Be (no dash) fails | Use v5 syntax: Should -Be (with dash prefix) |
Assert-MockCalled not recognized | Use v5 syntax: Should -Invoke |
| Mock has no effect | Check scope — mocks in It only apply to that It; use BeforeAll/BeforeEach for broader scope |
Should -Throw doesn't catch cmdlet errors | Most cmdlet errors are non-terminating — wrap with { cmd -ErrorAction Stop } or set $ErrorActionPreference = 'Stop' in BeforeEach |
| Tests pass on Windows but fail on Linux | Use Join-Path not string concatenation; match exact file casing; avoid Windows-only cmdlets (Registry, EventLog) |
Mocking Rules
Place mocks in
BeforeAll(shared) orBeforeEach(reset per test)Mock where the command is called from — use
-ModuleNameto mock inside a module's scopeUse
-ParameterFilterfor selective mocking (noparam()block needed in v5)Verify calls with
Should -Invoke— default scope insideItcounts only that test's callsUse
InModuleScopesparingly and as narrowly as possible — preferMock -ModuleNamefor testing via public APIInside mock bodies, use
$PesterBoundParametersnot$PSBoundParametersIf a test needs more than 3 mocks, flag it as a design smell
Non-Obvious Assertions
Most Should operators are self-explanatory. These are the ones agents get wrong:
Should -Throwrequires a scriptblock:{ risky-op } | Should -Throw— not a direct callShould -Containis for collections — useShould -Befor scalar equalityShould -HaveParametervalidates cmdlet signatures:Get-Command X | Should -HaveParameter 'Name' -MandatoryShould -Invokeverifies mock calls:Should -Invoke Get-Item -Times 1 -Exactly
Cross-Platform
Prefer
pwsh(PowerShell 7+) unless the repo explicitly targets Windows PowerShell 5.1Use
Join-Pathfor paths — never string concatenation with\Linux/macOS file systems are case-sensitive — match exact casing in imports and paths
Windows ships Pester 3.4.0 — if v5 is needed:
Install-Module Pester -Force -SkipPublisherCheckCheck
$PSVersionTable.PSEditionto detect Core vs Desktop
Skip Coverage Tools
Do not configure or run coverage tools (Pester CodeCoverage, JaCoCo export). Coverage is measured separately by the evaluation harness.
Requirements and compatibility
Written for: Claude Code
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Claude Code frontmatter, Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- .NET (Microsoft)
- Publisher
- .NET (Microsoft) (Official)
- Source
- dotnet/skills · plugins/dotnet-test/skills/code-testing-extensions · commit 96c3d68
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by .NET (Microsoft).
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download code-testing-extensions.zip