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/ruby.md
Ruby Extension
Language-specific guidance for Ruby test generation.
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 modules already covered by existing specs.
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 files under lib/ or app/ | git log --diff-filter=A --name-only -5 -- 'lib/**' 'app/**' |
Files referenced by spec_helper.rb / rails_helper.rb | grep -nE "^\s*require(_relative)?\s" spec/spec_helper.rb spec/rails_helper.rb 2>/dev/null |
| Modules with no matching spec | compare lib/**/*.rb against spec/**/*_spec.rb paths |
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 I/O, no global state).
Located under a conventional source root (
lib/,app/models/,app/services/).Have no existing matching
*_spec.rb/*_test.rb.
If spec/spec_helper.rb already requires one specific file (e.g. require "string_utils"), that file is almost certainly the target — start there.
Test Placement Contract
RSpec only discovers specs under spec/ by default, and verification harnesses (CI, msbench, coverage tools) typically scope discovery to spec/ alone. Place every spec there, mirroring the source layout:
| Source | Spec |
|---|---|
lib/string_utils.rb | spec/string_utils_spec.rb |
lib/foo/bar.rb | spec/foo/bar_spec.rb |
app/models/user.rb (Rails) | spec/models/user_spec.rb |
A spec placed anywhere outside spec/ (e.g. next to the source under lib/) will be invisible to bundle exec rspec and to the harness. The same applies to Minitest: place tests under test/ and use *_test.rb naming.
Gem-monorepo trap (fastlane, ruby/ruby, large gems with sub-gems): if the repo contains multiple */spec/ directories (each sub-gem with its own specs), bundle exec rspec from the repo root only loads ./spec/ by default — sub-gem specs are invisible to the harness. Either:
place the new spec inside the root
./spec/(with arequire_relativeto the sub-gem'slib/), orrun the sub-gem's
bundle exec rspecfrom the sub-gem dir AND verify in the Harness Discovery Check below that the root command also enumerates it (often it won't — you'll need to extend.rspecwith--default-pathor the rootRakefile's test task).
For interpreter-build repos (ruby/ruby itself) the test runner requires make test-all after make miniruby — ruby test/foo_test.rb alone is not what the harness runs.
First-Test Sanity Loop
After writing the first spec — before writing any others:
Run
bundle exec rspec --dry-runand confirm the example count is> 0. If it is0, RSpec is not seeing your file; fix the location, filename, or$LOAD_PATHbefore continuing.Run the spec (
bundle exec rspec spec/<your_spec>.rb); fixLoadError, missingrequire, or constant errors before adding more tests.Only then expand to cover the remaining methods.
This catches placement and load-path 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 example count went up by at least the number of tests you generated. CI/msbench/coverage harnesses do not know which file or sub-gem dir you targeted; they run the framework's default discovery from the repo root, so a spec that passes via bundle exec rspec fastlane_core/spec/foo_spec.rb is still worthless if bundle exec rspec --dry-run from the repo root doesn't enumerate it.
Choose the repository's configured runner before execution. Run the selected
commands from the repo root in the same Bash process as set -euo pipefail,
and require exit code zero before using any count as evidence. Do not suppress
stderr, pipe the runner into a counting command, or switch runners after failure.
For RSpec, use its dry-run example summary:
set -euo pipefail
bundle exec rspec --dry-run --format progressFor Minitest without a repository-supported discovery mode, run the configured
real test task and use its actual <N> runs, <N> assertions summary, not the number
of Rake tasks. For a repository whose harness uses rake test:
set -euo pipefail
bundle exec rake testIf the harness instead uses bin/rails test or another task, substitute that
command before execution; it is not a fallback for a failed selected task.
For custom runners (Homebrew, ruby/ruby, etc.), use the repository's documented
discovery mode or real harness-equivalent test task, with the same exit-status
requirements.
Require a successful runner exit and a nonzero test/example count, then compare
the baseline and updated summaries for the same harness scope. If the count did
not increase, your spec is invisible to the harness. Move it into ./spec/,
extend .rspec/Rakefile so the harness picks up the sub-gem dir, or switch to a
require_relative strategy from a root-level spec. A failed runner or missing
summary is a blocker, not evidence of empty discovery. 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
spec/**/*_spec.rb(RSpec) ortest/**/*_test.rb(Minitest) and copy their style (matchers, helpers, factories, contexts)Gemfile/Gemfile.lock— Ruby version, test framework, supporting gems (rspec,minitest,factory_bot,webmock,vcr,rails).ruby-version/.tool-versions— pinned Ruby versionTest helpers —
spec/spec_helper.rb,spec/rails_helper.rb,test/test_helper.rb— these dictate the load path, requires, and global configRake tasks —
Rakefilemay define adefaulttask that runs the full test suite
Use the framework the repo already uses. Do not introduce RSpec into a Minitest project (or vice versa).
Toolchain Detection
| Indicator | Manager | Run prefix |
|---|---|---|
Gemfile.lock | Bundler | bundle exec <cmd> |
.ruby-version + rbenv | rbenv | combine with bundle exec |
mise.toml / asdf .tool-versions | mise/asdf | the wrapper handles version selection; still use bundle exec |
| Plain Ruby, no Bundler | system Ruby | ruby <file> (rare in real projects) |
Always run inside bundle exec if a Gemfile.lock is present — otherwise you may pick up a system gem version that disagrees with the lockfile.
Build Commands
Ruby is interpreted — there is no compile step. The closest validations:
| Scope | Command |
|---|---|
| Syntax check | ruby -c path/to/file.rb |
| Lint (RuboCop) | bundle exec rubocop path/to/file.rb |
| Type check (Sorbet) | bundle exec srb tc (only if sorbet/ dir exists) |
| Type check (RBS/Steep) | bundle exec steep check |
For Rails: load all classes once with bundle exec rails zeitwerk:check to catch missing constants before running tests.
Test Commands
RSpec
| Scope | Command |
|---|---|
| All specs | bundle exec rspec |
| Single file | bundle exec rspec spec/models/widget_spec.rb |
| Single line | bundle exec rspec spec/models/widget_spec.rb:42 |
| By name | bundle exec rspec -e "creates a widget" |
| Tagged | bundle exec rspec --tag focus |
| Fail fast | bundle exec rspec --fail-fast |
| Documentation format | bundle exec rspec --format documentation |
Minitest
| Scope | Command |
|---|---|
| All tests | bundle exec rake test (Rails) or `bundle exec ruby -Ilib -Itest -e 'Dir.glob("./test/**/*_test.rb").each { |
| Single file | bundle exec ruby -Itest test/models/widget_test.rb |
| Single test | bundle exec ruby -Itest test/models/widget_test.rb -n test_creates_widget |
| By name pattern | ... -n /pattern/ |
Rails (any framework)
| Scope | Command |
|---|---|
| Default suite | bin/rails test (Minitest) or bundle exec rspec |
| Single Rails test file | bin/rails test test/models/widget_test.rb:42 |
| System tests | bin/rails test:system |
Always prefer the wrapper script (bin/rails, bin/rspec) when present — they enforce the project's loader/setup.
Lint Command
bundle exec rubocop— autocorrect withbundle exec rubocop -A(only if existing tests already conform; do not autocorrect unrelated files)bundle exec standardrb --fixifstandardis in the GemfileSome Rails projects add
rubocop-rails,rubocop-rspec,rubocop-performance— they enforce extra rules
Project Layout and Loading
| Layout | Test placement |
|---|---|
| Plain gem (RSpec) | spec/ mirrors lib/ (e.g. lib/foo/bar.rb → spec/foo/bar_spec.rb) |
| Plain gem (Minitest) | test/ mirrors lib/ (e.g. test/foo/bar_test.rb) |
| Rails (RSpec) | spec/models, spec/controllers, spec/requests, spec/system, etc. |
| Rails (Minitest) | test/models, test/controllers, test/integration, test/system |
Loading source code:
RSpec:
spec/spec_helper.rbtypically doesrequire 'my_gem'or sets$LOAD_PATH. Match its pattern in new specs byrequire 'spec_helper'(orrequire 'rails_helper'in Rails)Minitest: each
_test.rbtypicallyrequire 'test_helper'Rails uses Zeitwerk autoloading — do not add
require_relative '../../app/models/widget'; justrequire 'rails_helper'and reference the constant
Test File Naming
| Framework | File suffix | Class/example |
|---|---|---|
| RSpec | _spec.rb | RSpec.describe Widget do ... end, it "..." do ... end |
| Minitest (classic) | _test.rb | class WidgetTest < Minitest::Test, methods def test_... |
| Minitest (spec) | _test.rb | describe Widget do ... it "..." do ... end end |
| Rails Minitest | _test.rb | class WidgetTest < ActiveSupport::TestCase |
RSpec Template
require 'spec_helper'
require 'calculator'
RSpec.describe Calculator do
subject(:calculator) { described_class.new }
describe '#add' do
it 'returns the sum of two positive numbers' do
expect(calculator.add(2, 3)).to eq(5)
end
context 'with negative numbers' do
it 'returns the correct sum' do
expect(calculator.add(-1, 1)).to eq(0)
end
end
it 'raises when given non-numeric input' do
expect { calculator.add('a', 1) }.to raise_error(TypeError)
end
end
endCommon Errors
| Error | Fix |
|---|---|
LoadError: cannot load such file -- foo | Missing require or load path; check spec_helper.rb for the established pattern instead of patching $LOAD_PATH ad hoc |
NameError: uninitialized constant X | Constant isn't loaded — in Rails, ensure you require rails_helper; in plain Ruby, add the appropriate require |
ArgumentError: wrong number of arguments (given X, expected Y) | Read the method signature; pass keyword vs positional args correctly |
NoMethodError: undefined method 'foo' for nil:NilClass | Test setup left a value nil; check let/before ordering and factory data |
Failure/Error: ... received :foo with unexpected arguments (RSpec) | Tighten the matcher: with(hash_including(...)) or relax to with(any_args) deliberately |
expected #<...> to receive :foo (1 time) but received it 0 times | Either the code path didn't call the stub, or you stubbed the wrong receiver |
DEPRECATION WARNING (Rails) | Address the deprecation rather than silencing it; tests that warn today break tomorrow |
ActiveRecord::PendingMigrationError | Run bin/rails db:migrate RAILS_ENV=test before tests |
Mysql2::Error / PG::ConnectionBad in CI | Tests need a database — check config/database.yml and CI service containers |
Capybara::ElementNotFound (system tests) | Use find with explicit waits; do not add sleep |
Mocking Rules (RSpec)
Use
instance_double(Klass)andclass_double(Klass)— they verify that the method actually exists, unlikedoubleallow(obj).to receive(:method).and_return(value)for stubs;expect(obj).to receive(:method)for interaction expectationsPrefer
instance_doubleover plaindouble; prefer dependency injection overallow_any_instance_ofUse
letfor memoized helpers; uselet!only when the side effect must run before each exampleAvoid global state mutation in tests — wrap in
aroundblocks or useClimateControlfor env varsFor HTTP, use
webmock(stub_request(:get, ...)) orvcrcassettes if the project already uses themIf a test needs more than 3 mocks, flag it as a design smell
Mocking Rules (Minitest)
Use
Minitest::Mockfor simple cases:mock = Minitest::Mock.new; mock.expect(:method, return_value, [arg])For richer mocking, projects commonly add
mocha:obj.expects(:method).returns(value)(intest_helper.rb:require 'mocha/minitest')Always verify mocks at end of test (
mock.verifyforMinitest::Mock); Mocha verifies automatically
Rails Specifics
Use the smallest spec type that covers the behavior: model spec for pure logic, request spec for HTTP, system spec only when JS/UI matters
rails-controller-testinggem must be present forassigns(:foo)andassert_templateActiveJob::TestHelperandActiveSupport::Testing::TimeHelpers(travel_to) come with Rails — use them instead ofTimecopif Rails ≥ 5Use fixtures only if the project already uses them;
factory_botis more common in modern Rails appsDatabase transactions wrap each test by default — for system tests with browser drivers, use
DatabaseCleanerstrategies the project already configures
Dependency Installation (Last Resort)
Only add gems after investigation confirms they are missing. Edit Gemfile:
group :test do
gem 'rspec'
gem 'webmock'
endThen run:
bundle installNever gem install outside Bundler — it bypasses the lockfile and changes the global Ruby environment.
Skip Coverage Tools
Do not configure or run coverage tools (SimpleCov). 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