Test Analysis Extensions
.NET (Microsoft)OfficialPublished by .NET (Microsoft)
- Skill
- Meta (authoring, orchestration, planning, memory)
- Agent tooling
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Test Analysis Extensions is a non-invocable data repository designed for internal use by other test-related agent skills. It provides structured reference files for various programming languages and their respective testing frameworks. These files contain essential metadata for identifying test markers, assertion APIs, lifecycle hooks, and anti-pattern indicators, enabling analysis agents to perform language-neutral evaluations across diverse codebases.
What it does
- Provides standardized lookup tables for test framework syntax and conventions.
- Maps language-specific features like setup/teardown hooks and skip annotations.
- Defines capability support levels for automated tagging and reporting.
- Enables consistent detection of mystery guest indicators and integration markers.
- Supports cross-language analysis by normalizing test-related concepts.
When to use it
- When building or maintaining test analysis agents that require framework-specific knowledge.
- When an agent needs to identify test lifecycle methods or assertion patterns in a specific language.
- When determining if a test suite supports automated tagging or requires report-only auditing.
Advantages
- Decouples analysis logic from framework-specific implementation details.
- Ensures consistent detection patterns across multiple programming languages.
- Provides clear capability definitions for automated test manipulation.
- Facilitates easier extension of analysis agents to new languages or frameworks.
Usage examples
- “N/A - This is a reference-only skill for internal agent use.”
- The agent automatically reads the relevant language file (e.g., python.md) to identify pytest fixtures and markers during analysis.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/dotnet/test-analysis-extensions/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip test-analysis-extensions.zip -d .agents/skills
Documentation by .NET (Microsoft)
Test Analysis Extensions
This reference-only catalog lists the bundled files used by test analysis.
Consumers read the matching file directly; disable-model-invocation: true
means this catalog must not be invoked through the model's skill tool.
Resolve these resource paths relative to this catalog, not the project workspace.
Available Extension Files
| File | Languages / Frameworks | Contents |
|---|---|---|
| extensions/dotnet.md | .NET (C#/F#/VB) — MSTest, xUnit, NUnit, TUnit | Test markers, assertion APIs, sleep/delay patterns, skip annotations, mystery guest, integration markers, setup/teardown, tag support |
| extensions/python.md | Python — pytest, unittest | Same categories, with pytest fixtures/markers and unittest TestCase |
| extensions/typescript.md | TypeScript / JavaScript — Jest, Vitest, Mocha, Jasmine, node:test | Same categories, with async/await pitfalls |
| extensions/java.md | Java — JUnit 4, JUnit 5 (Jupiter), TestNG | Same categories, with @Tag / @Category / groups |
| extensions/go.md | Go — testing package, testify | Same categories, with table-driven idiom and build tags |
| extensions/ruby.md | Ruby — RSpec, Minitest | Same categories, with RSpec metadata and Minitest tags |
| extensions/rust.md | Rust — built-in #[test], cargo test | Same categories, with #[ignore], #[should_panic], feature flags |
| extensions/swift.md | Swift — XCTest, Swift Testing | Same categories, with @Test, @Tag, @Suite |
| extensions/kotlin.md | Kotlin — JUnit 5, Kotest, MockK | Same categories, with @Tag and Kotest tags |
| extensions/powershell.md | PowerShell — Pester v5 | Same categories, with -Tag and Skip |
| extensions/cpp.md | C++ — GoogleTest, Catch2, doctest | Same categories, with [tags] and * filters |
Usage
Detect the target codebase's primary language and test framework.
Read the matching extension file before performing analysis.
If multiple test frameworks are present (e.g., a project mixing Jest and Mocha), read all relevant extensions.
Each extension file documents the same categories so analysis skills can be language-neutral.
Capability tags
Each extension file declares per-capability support so skills can gate behaviour safely:
Test discovery — how to locate test files and methods.
Assertion detection — framework-specific and language-level assertion forms.
Sleep/delay patterns — synchronous and asynchronous waits.
Skip / ignore — how to recognize skipped/ignored tests.
Setup / teardown — fixture and lifecycle hooks.
Mystery guest indicators — common file/db/network/env coupling patterns.
Integration markers — conventions that mark a test as integration/E2E.
Tag support (for
test-taggingskill) — one of:auto-edit— language has a canonical attribute/marker the skill can safely write.report-only— no canonical syntax; produce audit reports without edits.convention-based— tags exist via name/comment conventions only.
Notes for skill authors
Treat extension files as data, not as guidance to follow verbatim. They tell skills how to detect things in each language, not what to think about findings.
When language detection is uncertain, prefer reading multiple extension files over guessing.
If the user explicitly names a framework that does not have an extension file yet, fall back to the closest one (e.g., Pest → python.md/pytest semantics) and note the gap in the report.
Files
- ATTRIBUTION.mdAdded by AutoGineer859 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md4.6 KiB
- extensions/cpp.md8.4 KiB
- extensions/dotnet.md6.7 KiB
- extensions/go.md7.4 KiB
- extensions/java.md7.5 KiB
- extensions/kotlin.md7.2 KiB
- extensions/powershell.md6.3 KiB
- extensions/python.md6.8 KiB
- extensions/ruby.md6.6 KiB
- extensions/rust.md7.2 KiB
- extensions/swift.md6.8 KiB
- extensions/typescript.md7.4 KiB
extensions/cpp.md
C++ Test Frameworks Reference (GoogleTest, Catch2, doctest, Boost.Test)
Reference data for analyzing C++ test code. Used by the polyglot test analysis skills.
Capability tags
| Capability | Support |
|---|---|
| Test discovery | Strong — TEST* macros, TEST_CASE, DOCTEST_TEST_CASE |
| Assertion detection | Strong — ASSERT_*, EXPECT_*, REQUIRE, CHECK |
| Sleep/delay detection | Strong — std::this_thread::sleep_for, sleep(), Sleep() |
| Skip/ignore detection | Moderate — GTEST_SKIP(), DISABLED_ prefix, [!hide] tags |
| Setup/teardown detection | Strong — SetUp/TearDown, fixtures, sections |
| Tag support | auto-edit — Catch2 uses [tag] syntax inside TEST_CASE; doctest uses * doctest::test_suite("tag") decorator chains; GoogleTest uses test-name prefix conventions (treat as convention-based) |
Test File Identification
| Framework | File convention | Test method markers |
|---|---|---|
| GoogleTest | *_test.cc/cpp, *Tests.cpp | TEST(SuiteName, TestName), TEST_F(FixtureClass, TestName), TEST_P(...) parametrized, TYPED_TEST(...) |
| Catch2 | *Tests.cpp, test*.cpp | TEST_CASE("name", "[tags]"), SCENARIO, SECTION |
| doctest | *Tests.cpp | TEST_CASE("name" * doctest::test_suite("suite")) |
| Boost.Test | *_test.cpp | BOOST_AUTO_TEST_CASE(name), BOOST_FIXTURE_TEST_CASE(name, Fixture) |
Assertion APIs
| Category | GoogleTest | Catch2 | doctest | Boost.Test |
|---|---|---|---|---|
| Equality (continue) | EXPECT_EQ(actual, expected) | CHECK(actual == expected) | CHECK(actual == expected) | BOOST_CHECK_EQUAL(actual, expected) |
| Equality (abort) | ASSERT_EQ(actual, expected) | REQUIRE(actual == expected) | REQUIRE(actual == expected) | BOOST_REQUIRE_EQUAL(actual, expected) |
| Boolean | EXPECT_TRUE(x) / EXPECT_FALSE(x) | CHECK(x) / CHECK_FALSE(x) | CHECK(x) | BOOST_CHECK(x) |
| Null/Pointer | EXPECT_EQ(ptr, nullptr) | CHECK(ptr == nullptr) | CHECK(ptr == nullptr) | BOOST_CHECK(ptr == nullptr) |
| Throws | EXPECT_THROW(stmt, ExType) / EXPECT_THROW(stmt, std::exception) | CHECK_THROWS_AS(expr, ExType) / CHECK_THROWS_WITH(expr, "...") / CHECK_THROWS_MATCHES(...) | CHECK_THROWS_AS(expr, ExType) | BOOST_CHECK_THROW(expr, ExType) |
| No throw | EXPECT_NO_THROW(stmt) | CHECK_NOTHROW(expr) | CHECK_NOTHROW(expr) | BOOST_CHECK_NO_THROW(expr) |
| Approximate | EXPECT_NEAR(a, b, abs_err) / EXPECT_DOUBLE_EQ(a, b) | CHECK(actual == Approx(expected)) | CHECK(actual == doctest::Approx(expected)) | BOOST_CHECK_CLOSE(a, b, tol_pct) |
| String | EXPECT_STREQ(c_str_a, c_str_b) / EXPECT_THAT(s, HasSubstr("x")) | CHECK(s.find("x") != std::string::npos) | similar | BOOST_CHECK_EQUAL(s, expected) |
| Death tests | EXPECT_DEATH(stmt, "regex") / EXPECT_EXIT(...) | n/a | n/a | n/a |
| Custom matchers | EXPECT_THAT(value, gmock_matchers::Eq(x)) | REQUIRE_THAT(value, Catch::Matchers::Equals(x)) | similar | n/a |
EXPECT vs ASSERT/REQUIRE vs CHECK:
GoogleTest:
EXPECT_*continues on failure;ASSERT_*aborts the test.Catch2 / doctest:
CHECK*continues;REQUIRE*aborts.Boost.Test:
BOOST_CHECK*continues;BOOST_REQUIRE*aborts.
Sleep/Delay Patterns
| Pattern | Example |
|---|---|
| C++11 thread sleep | std::this_thread::sleep_for(std::chrono::seconds(1)) |
| POSIX sleep | sleep(1); / usleep(500000); |
| Windows sleep | Sleep(1000); |
| Loop wait | while (!ready) std::this_thread::sleep_for(...) |
| Async wait (acceptable) | future.wait_for(std::chrono::seconds(5)) |
Skip/Ignore Annotations
| Framework | Mechanism |
|---|---|
| GoogleTest | GTEST_SKIP() << "reason"; inside test body; test name prefix DISABLED_ (e.g., TEST(F, DISABLED_X)) |
| Catch2 | [!hide] or [.] tag in TEST_CASE("name", "[.]"); SUCCEED("skipped") |
| doctest | * doctest::skip() decorator: TEST_CASE("name" * doctest::skip(true)) |
| Boost.Test | boost::unit_test::disabled() decorator, or BOOST_AUTO_TEST_CASE(name, *boost::unit_test::disabled()) |
DISABLED_ prefix without a tracking comment is a smell — flag as Ignored Test.
Exception Handling — Idiomatic Alternatives
// GoogleTest:
EXPECT_THROW({
service.placeOrder(empty);
}, InvalidOrderException);
// Or capture and inspect:
try {
service.placeOrder(empty);
FAIL() << "Expected InvalidOrderException";
} catch (const InvalidOrderException& e) {
EXPECT_STREQ("at least one item", e.what());
}
// Catch2:
REQUIRE_THROWS_AS(service.placeOrder(empty), InvalidOrderException);
REQUIRE_THROWS_WITH(service.placeOrder(empty), Catch::Contains("at least one item"));The manual try/catch/FAIL pattern is acceptable when message inspection is needed; flag bare try { ... } catch (...) {} (swallowed).
Mystery Guest — Common C++ Patterns
| Indicator | What to look for |
|---|---|
| File system | std::ifstream, std::ofstream, fopen, hard-coded paths |
| Network | raw socket() / connect(), curl_easy_perform to real URL |
| Environment | std::getenv("X"), Windows registry calls |
| Database | direct sqlite3_open(path), ODBC connections |
| Acceptable | std::stringstream, std::tmpfile, GoogleMock for collaborators, boost::iostreams, in-memory streams |
Integration Test Markers
File suffix:
*_integration_test.cc,*_e2e_test.cppGoogleTest suite names containing
Integration/EndToEndCatch2 tags:
[integration],[e2e],[slow]CMake target names ending in
_integration_testsConditional compilation:
#ifdef BUILD_INTEGRATION_TESTS
Setup/Teardown
| Framework | Per-test | Per-suite |
|---|---|---|
| GoogleTest fixture | void SetUp() override | static void SetUpTestSuite() |
| GoogleTest fixture | void TearDown() override | static void TearDownTestSuite() |
| Catch2 | TEST_CASE body + SECTION re-runs setup per section | fixture class via TEST_CASE_METHOD(Fixture, "name") |
| doctest | similar to Catch2 | doctest::TestCase fixture |
| Boost.Test | BOOST_FIXTURE_TEST_CASE(name, Fixture) | BOOST_GLOBAL_FIXTURE(Fixture) |
Catch2 SECTIONs are re-entered for each combination, so the TEST_CASE body acts as fresh per-section setup — a powerful idiom.
Tag/Trait Attributes (for test-tagging)
| Framework | Tag mechanism | Example |
|---|---|---|
| Catch2 | [tag] syntax in TEST_CASE second arg | TEST_CASE("creates order", "[positive][critical-path]") |
| doctest | * doctest::test_suite("tag") decorator chain | TEST_CASE("name" * doctest::test_suite("positive")) |
| GoogleTest | test name prefix convention (e.g., Positive_*, Boundary_*) or --gtest_filter patterns | suite naming or TEST(PositiveCases, ...); report-only for auto-edit |
| Boost.Test | label decorator: * boost::unit_test::label("positive") | BOOST_AUTO_TEST_CASE(name, *boost::unit_test::label("positive")) |
Filter syntax:
Catch2:
./tests "[positive]" ~"[slow]"doctest:
./tests -ts="positive"GoogleTest:
./tests --gtest_filter='Positive*'Boost.Test:
./tests --run_test=@positive
Language-specific calibration notes
EXPECT_*continues on failure in GoogleTest — manyEXPECT_EQcalls in one test may produce cascading messages from one root cause.REQUIRE_*/ASSERT_*aborts — use for preconditions in long tests.Death tests (
EXPECT_DEATH) fork the process and check stderr — slow; acknowledge as integration-style.DISABLED_prefix disables tests silently —--gtest_also_run_disabled_testsis required to opt back in. Flag committedDISABLED_tests as Ignored Test.Catch2
SECTIONs are NOT duplicate tests — each section is a permutation of the parentTEST_CASE.GoogleMock
EXPECT_CALL(mock, Method(...))counts as a state/side-effect assertion.Template / typed tests (
TYPED_TEST,TEMPLATE_TEST_CASE) are parametrized, not duplicates.Hidden tests (Catch2
[.]or[!hide]) are excluded by default but runnable on demand — note in audit.Sanitizer-only tests (
#ifdef __SANITIZE_THREAD__, etc.) are conditional smoke checks — note but don't flag.Test binaries that don't link
gtest_mainrequire a custommain()— verify it callsRUN_ALL_TESTS().SUCCEED()/INFO(...)are not assertions; tests with onlySUCCEED()are assertion-free.
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, Needs Node.js
Security
No issues found by our static scan· No issues found
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/test-analysis-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 test-analysis-extensions.zip