Generated banner for Code Testing Extensions
Generated logo for Code Testing Extensions

Code Testing Extensions

.NET (Microsoft)OfficialPublished by .NET (Microsoft)

  • Skill
  • Guidelines
  • Software development
  • MIT
  • Low risk

From the author

Provides file paths to language-specific extension files for the code-testing pipeline. Read this reference-only catalog for extension guidance files (e.g., dotnet.md for .NET, cpp.md for C++). Agents and skills read its bundled files directly; do not invoke this catalog through the model's skill tool.
— the description by .NET (Microsoft)

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

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/dotnet/code-testing-extensions/download
  2. Unzip 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

FileLanguageContents
extensions/dotnet.md.NET (C#/F#/VB)Build commands, test commands, project reference validation, common CS error codes, MSTest template
extensions/python.mdPythonFramework-adaptive test commands (pytest, custom runners), project layout detection, mocking guidelines, common errors
extensions/typescript.mdTypeScript/JavaScriptBuild/test commands (Jest/Vitest/Mocha), framework detection, mocking, TS-specific considerations
extensions/powershell.mdPowerShellTest commands (Pester v5), module import patterns, discovery/run pitfalls, mocking, common errors
extensions/cpp.mdC++Testing internals with friend declarations
extensions/go.mdGogo test commands, table-driven tests, integration vs unit layout, mocking via interfaces, common errors
extensions/java.mdJavaMaven/Gradle commands, JUnit 4/5 and TestNG detection, Mockito, Spring Boot slices, common errors
extensions/rust.mdRustcargo test commands, unit vs integration vs doc tests, features, async test harnesses, common errors
extensions/ruby.mdRubyRSpec and Minitest commands, Bundler usage, Rails specifics, mocking patterns, common errors
extensions/swift.mdSwiftSPM and Xcode test commands, XCTest vs Swift Testing, @testable import, async/throws tests, common errors
extensions/kotlin.mdKotlinGradle 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.mdPythonConcrete pipeline examples (pytest): research, plan, generated test file, fix cycles, final report
extensions/typescript-examples.mdTypeScript/JavaScriptConcrete pipeline examples (Vitest, applicable to Jest): research, plan, generated test file, fix cycles, final report
extensions/go-examples.mdGoConcrete pipeline examples (standard testing): research, plan, table-driven test file, fix cycles, final report
extensions/java-examples.mdJavaConcrete 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

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.

GoalCommand
List uncommitted edits + untracked filesgit 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.rbgrep -nE "^\s*require(_relative)?\s" spec/spec_helper.rb spec/rails_helper.rb 2>/dev/null
Modules with no matching speccompare lib/**/*.rb against spec/**/*_spec.rb paths

Prefer targets that match all of:

  1. Untracked or recently added (git status / git log --diff-filter=A).

  2. Small and pure (a few hundred lines, no I/O, no global state).

  3. Located under a conventional source root (lib/, app/models/, app/services/).

  4. 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:

SourceSpec
lib/string_utils.rbspec/string_utils_spec.rb
lib/foo/bar.rbspec/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 a require_relative to the sub-gem's lib/), or

  • run the sub-gem's bundle exec rspec from 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 .rspec with --default-path or the root Rakefile'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:

  1. Run bundle exec rspec --dry-run and confirm the example count is > 0. If it is 0, RSpec is not seeing your file; fix the location, filename, or $LOAD_PATH before continuing.

  2. Run the spec (bundle exec rspec spec/<your_spec>.rb); fix LoadError, missing require, or constant errors before adding more tests.

  3. 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 progress

For 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 test

If 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:

  1. Existing tests — find spec/**/*_spec.rb (RSpec) or test/**/*_test.rb (Minitest) and copy their style (matchers, helpers, factories, contexts)

  2. Gemfile / Gemfile.lock — Ruby version, test framework, supporting gems (rspec, minitest, factory_bot, webmock, vcr, rails)

  3. .ruby-version / .tool-versions — pinned Ruby version

  4. Test helpers — spec/spec_helper.rb, spec/rails_helper.rb, test/test_helper.rb — these dictate the load path, requires, and global config

  5. Rake tasks — Rakefile may define a default task 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

IndicatorManagerRun prefix
Gemfile.lockBundlerbundle exec <cmd>
.ruby-version + rbenvrbenvcombine with bundle exec
mise.toml / asdf .tool-versionsmise/asdfthe wrapper handles version selection; still use bundle exec
Plain Ruby, no Bundlersystem Rubyruby <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:

ScopeCommand
Syntax checkruby -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
ScopeCommand
All specsbundle exec rspec
Single filebundle exec rspec spec/models/widget_spec.rb
Single linebundle exec rspec spec/models/widget_spec.rb:42
By namebundle exec rspec -e "creates a widget"
Taggedbundle exec rspec --tag focus
Fail fastbundle exec rspec --fail-fast
Documentation formatbundle exec rspec --format documentation
Minitest
ScopeCommand
All testsbundle exec rake test (Rails) or `bundle exec ruby -Ilib -Itest -e 'Dir.glob("./test/**/*_test.rb").each {
Single filebundle exec ruby -Itest test/models/widget_test.rb
Single testbundle exec ruby -Itest test/models/widget_test.rb -n test_creates_widget
By name pattern... -n /pattern/
Rails (any framework)
ScopeCommand
Default suitebin/rails test (Minitest) or bundle exec rspec
Single Rails test filebin/rails test test/models/widget_test.rb:42
System testsbin/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 with bundle exec rubocop -A (only if existing tests already conform; do not autocorrect unrelated files)

  • bundle exec standardrb --fix if standard is in the Gemfile

  • Some Rails projects add rubocop-rails, rubocop-rspec, rubocop-performance — they enforce extra rules

Project Layout and Loading

LayoutTest 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.rb typically does require 'my_gem' or sets $LOAD_PATH. Match its pattern in new specs by require 'spec_helper' (or require 'rails_helper' in Rails)

  • Minitest: each _test.rb typically require 'test_helper'

  • Rails uses Zeitwerk autoloading — do not add require_relative '../../app/models/widget'; just require 'rails_helper' and reference the constant

Test File Naming

FrameworkFile suffixClass/example
RSpec_spec.rbRSpec.describe Widget do ... end, it "..." do ... end
Minitest (classic)_test.rbclass WidgetTest < Minitest::Test, methods def test_...
Minitest (spec)_test.rbdescribe Widget do ... it "..." do ... end end
Rails Minitest_test.rbclass 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
end

Common Errors

ErrorFix
LoadError: cannot load such file -- fooMissing require or load path; check spec_helper.rb for the established pattern instead of patching $LOAD_PATH ad hoc
NameError: uninitialized constant XConstant 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:NilClassTest 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 timesEither 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::PendingMigrationErrorRun bin/rails db:migrate RAILS_ENV=test before tests
Mysql2::Error / PG::ConnectionBad in CITests 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) and class_double(Klass) — they verify that the method actually exists, unlike double

  • allow(obj).to receive(:method).and_return(value) for stubs; expect(obj).to receive(:method) for interaction expectations

  • Prefer instance_double over plain double; prefer dependency injection over allow_any_instance_of

  • Use let for memoized helpers; use let! only when the side effect must run before each example

  • Avoid global state mutation in tests — wrap in around blocks or use ClimateControl for env vars

  • For HTTP, use webmock (stub_request(:get, ...)) or vcr cassettes if the project already uses them

  • If a test needs more than 3 mocks, flag it as a design smell

Mocking Rules (Minitest)

  • Use Minitest::Mock for simple cases: mock = Minitest::Mock.new; mock.expect(:method, return_value, [arg])

  • For richer mocking, projects commonly add mocha: obj.expects(:method).returns(value) (in test_helper.rb: require 'mocha/minitest')

  • Always verify mocks at end of test (mock.verify for Minitest::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-testing gem must be present for assigns(:foo) and assert_template

  • ActiveJob::TestHelper and ActiveSupport::Testing::TimeHelpers (travel_to) come with Rails — use them instead of Timecop if Rails ≥ 5

  • Use fixtures only if the project already uses them; factory_bot is more common in modern Rails apps

  • Database transactions wrap each test by default — for system tests with browser drivers, use DatabaseCleaner strategies 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'
end

Then run:

bundle install

Never 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