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://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/kotlin.md

Kotlin Extension

Language-specific guidance for Kotlin test generation. For pure-Java codebases, use java.md instead.

Rule #1: Investigate the Repo First

Before writing any test or running any command, read:

  1. Existing tests — find files in src/test/kotlin/, src/commonTest/kotlin/, src/jvmTest/kotlin/, etc., and copy their style (framework, assertion library, mock library, coroutine helpers)

  2. Build file — build.gradle.kts / build.gradle — note Kotlin version, plugins (kotlin("jvm"), kotlin("multiplatform"), kotlin("android")), and dependencies { testImplementation(...) }

  3. gradle/libs.versions.toml — the version catalog if the repo uses one; reference aliases instead of hard-coded versions

  4. Wrapper script — always invoke ./gradlew (Unix) or .\gradlew.bat (Windows), never a system-installed Gradle

  5. Multiplatform layout — src/<sourceSet>/kotlin/ indicates KMP; tests live in matching *Test source sets (commonTest, jvmTest, nativeTest)

Use whatever framework the repo already uses (JUnit Jupiter, JUnit 4, Kotest, kotlin.test). Do not switch.

Project Type Detection

IndicatorProject type
kotlin("jvm") pluginPlain JVM Kotlin
kotlin("multiplatform") plugin with kotlin { jvm(); js(); ... }Kotlin Multiplatform
com.android.application / com.android.library pluginAndroid
org.springframework.boot pluginSpring Boot Kotlin
kotlin("jvm") + application pluginKotlin CLI / server

For Android, see also platform-specific test types: src/test/ for unit tests on the JVM, src/androidTest/ for instrumented tests on a device/emulator. They use different runners and gradle tasks.

Build Commands

ScopeCommand
Compile main + test (JVM)./gradlew compileTestKotlin
Full build./gradlew build
Skip tests./gradlew assemble
Single module./gradlew :module-name:build
KMP target only./gradlew :module:jvmTest (or linuxX64Test, etc.)
  • Use --console=plain to suppress Gradle's animated output

  • Use --build-cache (often default in CI) to reuse outputs

  • For Android: ./gradlew assembleDebug (build APK) and ./gradlew testDebugUnitTest (run unit tests)

Test Commands

ScopeCommand
All tests (JVM)./gradlew test
Single class./gradlew test --tests "com.example.WidgetTest"
Single method./gradlew test --tests "com.example.WidgetTest.add returns sum"
KMP all targets./gradlew allTests
KMP one target./gradlew jvmTest, ./gradlew jsTest, ./gradlew linuxX64Test
Android unit tests./gradlew testDebugUnitTest
Android instrumented./gradlew connectedDebugAndroidTest (requires device/emulator)
  • --tests accepts wildcards: --tests "*Widget*". Method names with spaces or backticks must be quoted: --tests "com.example.WidgetTest.creates a widget"

  • Use --rerun-tasks only when troubleshooting cache issues

  • For Kotest, the runner is registered with JUnit Platform — the standard ./gradlew test and --tests flags work the same way

Lint Command

Use the repo's lint tooling first:

  • ./gradlew ktlintCheck (autoformat: ./gradlew ktlintFormat) when ktlint is configured

  • ./gradlew detekt when detekt is configured

  • ./gradlew spotlessCheck / spotlessApply for the Spotless plugin

  • Android Studio's IDE inspections; ./gradlew lint (Android-only) for the Android Lint task

Project Layout

src/
├── main/kotlin/com/example/foo/Bar.kt
├── main/resources/
├── test/kotlin/com/example/foo/BarTest.kt   # mirrors production package
└── test/resources/

KMP layout:

src/
├── commonMain/kotlin/...        # shared
├── commonTest/kotlin/...        # shared tests using kotlin.test
├── jvmMain/kotlin/...
├── jvmTest/kotlin/...
├── jsMain/kotlin/...
└── jsTest/kotlin/...
  • Test classes mirror the production class's package so they can access internal members (Kotlin's internal is module-scoped — within the same Gradle module, including the test source set)

  • For KMP common tests, you can only import from kotlin.test and other multiplatform-aware libraries (e.g. kotlinx.coroutines.test, Kotest multiplatform, MockK on JVM only)

Test Framework Detection

DependencyFrameworkAnnotations / DSL
org.jetbrains.kotlin:kotlin-testkotlin.test (multiplatform)@Test, @BeforeTest, assertEquals, assertFailsWith
junit-jupiter-*JUnit 5@Test, @ParameterizedTest, @BeforeEach, @DisplayName
junit:junit:4.xJUnit 4@Test, @Before, @RunWith(JUnitPlatform::class) rare
io.kotest:kotest-runner-junit5Kotestclass FooSpec : FunSpec({ test("...") { ... } }) (DSL — many styles: StringSpec, BehaviorSpec, etc.)
org.spekframework.spek2:spek-dsl-jvmSpek 2object FooSpec : Spek({ describe(...) { it(...) {} } }) (legacy)

For Kotest, stick to the spec style the repo already uses — mixing styles is confusing.

Test Templates

JUnit 5
package com.example.foo

import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import kotlin.test.assertEquals

class CalculatorTest {

    @Test
    @DisplayName("add returns sum of two positive numbers")
    fun `add returns sum of two positives`() {
        val sut = Calculator()
        assertEquals(5, sut.add(2, 3))
    }

    @Test
    fun `divide by zero throws`() {
        val sut = Calculator()
        assertThrows<ArithmeticException> { sut.divide(1, 0) }
    }
}

Backticked method names (`like this`) are idiomatic for Kotlin tests because they read better in failure messages.

Kotest (StringSpec)
package com.example.foo

import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
import io.kotest.assertions.throwables.shouldThrow

class CalculatorSpec : StringSpec({
    "add returns sum of two positive numbers" {
        Calculator().add(2, 3) shouldBe 5
    }

    "divide by zero throws" {
        shouldThrow<ArithmeticException> { Calculator().divide(1, 0) }
    }
})

Coroutines

  • Use kotlinx-coroutines-test when it's already on the classpath; otherwise add it as a testImplementation only after confirming it is missing (see Dependency Installation)

  • Use runTest { ... } (replaces the older runBlockingTest) for suspend test bodies

  • For virtual time advance, use a TestDispatcher built from testScheduler — e.g. StandardTestDispatcher(testScheduler) or UnconfinedTestDispatcher(testScheduler) — rather than calling delay and waiting in real time

  • Inject a CoroutineDispatcher into production code instead of using Dispatchers.Main/IO directly — then swap it in tests via Dispatchers.setMain(testDispatcher)

@Test
fun `loads data eventually`() = runTest {
    val repo = FakeRepo()
    val dispatcher = StandardTestDispatcher(testScheduler)
    val sut = Loader(repo, dispatcher)
    sut.start()
    advanceUntilIdle()
    assertEquals(LoadState.Done, sut.state.value)
}

Common Errors

ErrorFix
Unresolved reference: XAdd the import; verify the test source set sees the production source set; for KMP, the dep may be declared only in jvmTest
Cannot access 'X': it is internal in module Yinternal is module-scoped, so a test in another Gradle module cannot see it. Move the test into the same module, expose a public seam (e.g. a *-testing artifact, or change visibility deliberately), or add the consuming module to the source module's friend modules via the Kotlin compiler -Xfriend-paths option. @VisibleForTesting does not widen Kotlin visibility
Class 'XTest' is not abstract and does not implement abstract member (Kotest spec)The spec class needs a no-arg constructor and a primary-constructor block — match the existing spec style
No tests found for given includes (Gradle)--tests pattern doesn't match; verify class name and that the framework's runner is registered on the test task (useJUnitPlatform())
kotlin.UninitializedPropertyAccessException: lateinit property X has not been initializedThe @BeforeEach (or BeforeTest) didn't run, or the field was reset; use lateinit only after confirming the lifecycle hook fires
IllegalStateException: Module with the Main dispatcher had failed to initializeCoroutines test needs Dispatchers.setMain(...) before launching anything that touches Dispatchers.Main; reset with Dispatchers.resetMain() in teardown
Mockito cannot mock final classKotlin classes are final by default — either use MockK (works with final classes) or apply the kotlin-allopen plugin scoped to a marker annotation
MissingMockKExceptionThe mock wasn't initialized; call MockKAnnotations.init(this) or use @MockK with @MockKExtension (JUnit 5)
KMP common test references a JVM-only APIMove the test to jvmTest, or use expect/actual declarations
Android: Method ... not mockedThe unit test runs on the JVM and the SDK class is just a stub — either use Robolectric, move the test to instrumented (androidTest), or refactor to inject the dependency

Mocking Rules

  • MockK is the de-facto standard for Kotlin (final classes, coroutine support): every { mock.foo() } returns 1, coEvery { mock.suspendFn() } returns 1, verify { mock.foo() }, coVerify { ... }

  • Mockito works on Kotlin too with mockito-kotlin extensions, but Kotlin classes are final by default — use Mockito's inline mock maker (default in Mockito 5+; the mockito-inline artifact for Mockito 3.x/4.x). mockito-subclass cannot mock final classes

  • Avoid mockkStatic/mockkObject for production code you control — refactor to a wrapper instead

  • Prefer constructor injection so you don't need framework annotations (@InjectMocks) at all

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

Android Specifics

  • Robolectric tests live under src/test/ and emulate the Android framework on the JVM — fast but imperfect

  • Instrumented tests live under src/androidTest/, require a connected device/emulator, and are slow — use sparingly

  • Compose UI tests use createComposeRule() and composeTestRule.onNodeWithText(...).performClick() — match the existing test setup if Compose is in the project

  • Hilt: use @HiltAndroidTest and HiltAndroidRule for instrumented tests; for unit tests pass fakes directly to ViewModels

Dependency Installation (Last Resort)

Only add dependencies after investigation confirms they are missing.

build.gradle.kts:

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
    testImplementation("io.mockk:mockk:1.13.10")
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")
}

tasks.test {
    useJUnitPlatform()
}

If the repo uses a version catalog, add to gradle/libs.versions.toml and reference via libs.junit.jupiter etc. Match the major versions already in use.

Skip Coverage Tools

Do not configure or run coverage tools (JaCoCo, Kover). 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) or .NET (Microsoft).

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download code-testing-extensions.zip