mirror of
https://github.com/dotnet/skills.git
synced 2026-09-20 09:49:54 +08:00
680292e04c
* Make dotnet-test analysis skills and auditor agent polyglot Five test analysis skills and the test-quality-auditor agent in plugins/dotnet-test previously activated only on .NET MSTest/xUnit/NUnit/ TUnit cues, even though the underlying techniques (assertion diversity, anti-pattern detection, pseudo-mutation gap analysis, academic smell catalog, trait tagging) apply equally to other test frameworks. This change makes them polyglot across .NET, Python (pytest/unittest), TypeScript/JavaScript (Jest/Vitest/Mocha/node:test), Java (JUnit/TestNG), Go, Ruby (RSpec/Minitest), Rust, Swift (XCTest/Swift Testing), Kotlin (JUnit/Kotest), PowerShell (Pester), and C++ (GoogleTest/Catch2/doctest). Changes ------- * New reference skill `test-analysis-extensions` with per-language extension files (dotnet, python, typescript, java, go, ruby, rust, swift, kotlin, powershell, cpp). Each documents test markers, assertion APIs, sleep / time / random APIs, skip annotations, setup/teardown, mystery-guest indicators, integration markers, and tag-support capability for the corresponding framework. * `assertion-quality`, `test-anti-patterns`, `test-gap-analysis`, `test-smell-detection`, `test-tagging` SKILL.md updated: frontmatter now lists all polyglot frameworks (keeping .NET trigger words for backward compat); bodies reference `test-analysis-extensions` and add per-language calibration (e.g., Go/Rust table-driven loops are idiomatic and not Conditional Test Logic; pytest bare `assert` is canonical; missing-await on async assertions is a new Critical smell). * `test-quality-auditor` agent now runs language detection, gates .NET-only pipeline steps (coverage-analysis, CRAP, detect-static- dependencies, testability migration, experimental dotnet skills), and recommends native tooling for non-.NET projects via an explicit Capability Matrix. * README updated to split sections by polyglot vs .NET-only. * New polyglot eval scenarios added (Python/pytest, TS/Jest, Java/JUnit) alongside existing C# scenarios in `test-anti-patterns`, `assertion-quality`, `test-smell-detection`. The .NET-only skills (writing-mstest-tests, migrate-*, coverage-analysis, crap-score, detect-static-dependencies, run-tests, filter-syntax, platform-detection, dotnet-test-frameworks, mtp-hot-reload, exp-*) are unchanged and continue to activate only for .NET work. Validated with skill-validator `check --plugin ./plugins/dotnet-test`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #707 review feedback * typescript.md: replace xpect.fail() recommendation (Jest has no such API) with hrow new Error(...) / explicit failing assertion. * test-tagging SKILL.md description: clarify that unittest has no canonical tag syntax (pytest markers are the auto-edit mechanism; unittest is report-only). Switch doctest reference to "decorators" rather than implying a Catch2-style [tags] mechanism exists. * test-tagging SKILL.md auto-edit list and table: use `* doctest::test_suite("tag")` decorator chain syntax for doctest in both the bullet list and the per-framework table, matching the example already shown. * cpp.md extension: spell out the Catch2 vs doctest tagging distinction in the capability matrix (Catch2 [tag], doctest * doctest::test_suite("tag") decorator). Validated with `dotnet run --project eng/skill-validator/src -- check --plugin ./plugins/dotnet-test` (23 skills + 11 agents). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
208 lines
12 KiB
YAML
208 lines
12 KiB
YAML
scenarios:
|
|
# ==========================================================================
|
|
# Scenario 1: Low assertion diversity — equality-heavy test suite
|
|
# ==========================================================================
|
|
|
|
- name: "Identify low assertion diversity in equality-dominated test suite"
|
|
prompt: |
|
|
I want to understand whether my PaymentService tests are actually
|
|
thorough. They all pass, but I'm not confident they'd catch real bugs.
|
|
Can you analyze the assertion quality and variety?
|
|
setup:
|
|
files:
|
|
- path: "PaymentService.Tests/PaymentService.Tests.csproj"
|
|
source: "fixtures/low-diversity/PaymentService.Tests/PaymentService.Tests.csproj"
|
|
- path: "PaymentService.Tests/PaymentProcessorTests.cs"
|
|
source: "fixtures/low-diversity/PaymentService.Tests/PaymentProcessorTests.cs"
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(diversity|variety|spread|shallow|narrow|limited|homogeneous|repetitive)"
|
|
- type: "output_matches"
|
|
pattern: "(AreEqual|equality|equal)"
|
|
- type: "output_matches"
|
|
pattern: "(exception|throw|error|negative|missing)"
|
|
- type: "exit_success"
|
|
rubric:
|
|
- "Identified that the vast majority of assertions are Assert.AreEqual, showing low assertion type diversity"
|
|
- "Noted the absence of exception assertions — no tests verify error handling behavior (e.g., invalid card, negative amounts)"
|
|
- "Identified GetReceipt test as having only a trivial Assert.IsNotNull without checking the receipt's content"
|
|
- "Noted that no tests verify collection contents in GetTransactionHistory — only the count is checked"
|
|
- "Recommended specific additional assertion types that would improve coverage (exception, collection, structural)"
|
|
- "Provided concrete examples of assertions that could be added to specific test methods"
|
|
timeout: 120
|
|
|
|
# ==========================================================================
|
|
# Scenario 2: Assertion-free smoke tests
|
|
# ==========================================================================
|
|
|
|
- name: "Flag assertion-free tests and trivial-only assertions"
|
|
prompt: |
|
|
Our QA team says these API smoke tests give us good coverage but I'm
|
|
suspicious. Analyze the assertion quality and depth in
|
|
`SmokeTests/ApiEndpointSmokeTests.cs` — specifically identify
|
|
assertion-free tests (tests that call methods without verifying
|
|
results) and tests with only trivial assertions like
|
|
`Assert.IsNotNull`. Report which tests are assertion-free, the overall
|
|
assertion quality, and concrete recommendations. Do not edit the
|
|
files.
|
|
setup:
|
|
files:
|
|
- path: "SmokeTests/SmokeTests.csproj"
|
|
source: "fixtures/assertion-free/SmokeTests/SmokeTests.csproj"
|
|
- path: "SmokeTests/ApiEndpointSmokeTests.cs"
|
|
source: "fixtures/assertion-free/SmokeTests/ApiEndpointSmokeTests.cs"
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(no assertion|zero assertion|assertion.free|without.*assert|missing.*assert|don.*assert|lack.*assert)"
|
|
- type: "output_matches"
|
|
pattern: "(5|five|62%|most|majority|several)"
|
|
- type: "exit_success"
|
|
rubric:
|
|
- "Identified that 5 out of 8 tests have zero assertions — they only call methods without verifying results"
|
|
- "Identified that the remaining 3 tests only use Assert.IsNotNull, which is a trivial assertion that doesn't verify content"
|
|
- "Explained that these tests give false security — code coverage may look good but correctness is not verified"
|
|
- "Recommended specific meaningful assertions for at least some of the assertion-free tests"
|
|
- "Distinguished between intentional smoke tests (acceptable if labeled as such) and tests masquerading as real verification"
|
|
timeout: 300
|
|
|
|
# ==========================================================================
|
|
# Scenario 3: Good assertion diversity — acknowledge well-tested code
|
|
# ==========================================================================
|
|
|
|
- name: "Recognize well-diversified assertion usage"
|
|
prompt: |
|
|
Can you evaluate the assertion quality in my UserService.Tests project?
|
|
I want to make sure my tests are thorough enough before we ship.
|
|
setup:
|
|
files:
|
|
- path: "UserService.Tests/UserService.Tests.csproj"
|
|
source: "fixtures/good-diversity/UserService.Tests/UserService.Tests.csproj"
|
|
- path: "UserService.Tests/UserManagerTests.cs"
|
|
source: "fixtures/good-diversity/UserService.Tests/UserManagerTests.cs"
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(good|strong|solid|diverse|well|thorough|comprehensive|varied)"
|
|
- type: "exit_success"
|
|
rubric:
|
|
- "Recognized that the test suite uses a variety of assertion types including equality, boolean, null, exception, and collection assertions"
|
|
- "Noted positive patterns: tests check multiple properties on returned objects, not just one field"
|
|
- "Acknowledged the negative assertions (Assert.IsNull for non-existent user, Assert.IsFalse for failed delete, Assert.AreNotEqual for role change)"
|
|
- "Acknowledged the exception assertions with specific exception types and parameter name verification"
|
|
- "If any gaps were identified, they were presented as minor enhancement opportunities rather than problems"
|
|
timeout: 300
|
|
|
|
# ==========================================================================
|
|
# Scenario 4: Self-referential assertions — tautological round-trip tests
|
|
# ==========================================================================
|
|
|
|
- name: "Identify self-referential assertions in identity and round-trip tests"
|
|
prompt: |
|
|
I want an assertion-quality analysis of my Config tests. They all pass
|
|
but I'm not sure they'd catch real bugs. Analyze the assertion quality
|
|
and depth in `ConfigService.Tests/ConfigTests.cs` — specifically
|
|
identify self-referential or tautological assertions where the test
|
|
asserts the output equals the input on identity / round-trip
|
|
operations. Report assertion-quality metrics (how many tests are
|
|
self-referential, which ones), explain why each flagged test fails to
|
|
verify real behavior, and recommend concrete improvements. Do not
|
|
edit the files — this is a read-only assertion-quality review.
|
|
setup:
|
|
files:
|
|
- path: "ConfigService.Tests/ConfigService.Tests.csproj"
|
|
source: "fixtures/self-referential/ConfigService.Tests/ConfigService.Tests.csproj"
|
|
- path: "ConfigService.Tests/ConfigTests.cs"
|
|
source: "fixtures/self-referential/ConfigService.Tests/ConfigTests.cs"
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(self.referent|tautolog|identity|input.*equals.*output|circular|same.*value|trivial.*round.?trip|round.?trip|set.*get|write.*read|proves nothing|not.*(testing|verif)|meaningless)"
|
|
- type: "output_matches"
|
|
pattern: "(GetTimeout|GetRetries|FormatConnectionString|ValidateKey)"
|
|
- type: "exit_success"
|
|
rubric:
|
|
- "Identified that multiple tests assert the output equals the input — a self-referential pattern that cannot catch transformation bugs"
|
|
- "Flagged GetTimeout_Default_ReturnsDefault and GetRetries_Default_ReturnsDefault as tautological — they assert that reading back a just-written value returns the same value without testing the default/fallback behavior the names suggest"
|
|
- "Flagged FormatConnectionString_RoundTrip as only proving round-trip identity without verifying the formatted string's actual structure or content"
|
|
- "Flagged ValidateKey_Valid_ReturnsSameKey as not exercising the validation logic — it only proves valid input passes through unchanged"
|
|
- "Noted that Serialize_Deserialize round-trip is potentially valid but should be accompanied by tests with edge-case inputs (special characters, nulls, empty strings)"
|
|
- "Recommended concrete improvements: test actual default values, test invalid keys, test formatted string structure, test edge-case serialization inputs"
|
|
reject_tools: ["bash", "edit", "create"]
|
|
timeout: 300
|
|
|
|
# ==========================================================================
|
|
# Scenario 5: Non-activation — user wants to run tests
|
|
# ==========================================================================
|
|
|
|
- name: "Decline request to write new tests from scratch"
|
|
prompt: |
|
|
I need to write unit tests for my InventoryTracker class.
|
|
It handles stock levels, reorder alerts, and warehouse transfers.
|
|
Can you help me write a full MSTest test suite from scratch?
|
|
expect_activation: false
|
|
setup:
|
|
files:
|
|
- path: "InventoryTracker.cs"
|
|
content: |
|
|
namespace Warehouse;
|
|
|
|
public sealed class InventoryTracker
|
|
{
|
|
public int GetStockLevel(string sku) => throw new NotImplementedException();
|
|
public void AddStock(string sku, int quantity) => throw new NotImplementedException();
|
|
public bool NeedsReorder(string sku) => throw new NotImplementedException();
|
|
}
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(TestMethod|TestClass|\\[Fact\\]|test)"
|
|
rubric:
|
|
- "Wrote test methods for the InventoryTracker class"
|
|
- "Covered multiple methods of the class"
|
|
timeout: 300
|
|
|
|
# ==========================================================================
|
|
# Scenario: Polyglot — shallow assertions in a Jest/TypeScript suite
|
|
# ==========================================================================
|
|
|
|
- name: "Polyglot: evaluate shallow assertions in a Jest/TypeScript OrderService suite"
|
|
prompt: |
|
|
Audit the assertion quality and depth of `tests/order.test.ts`. The
|
|
production code is `src/order.ts`. This is a Jest/TypeScript suite,
|
|
not .NET — apply the same assertion-quality catalog using
|
|
Jest equivalents (`toBeDefined`, `toBeTruthy`, `not.toBeNull`,
|
|
`toBe`, `.resolves`, `toThrow`).
|
|
|
|
Specifically check for: shallow / trivial-only assertions, always-true
|
|
assertions, missing `await` on async assertion chains (a silent-pass
|
|
smell), identity / self-comparing assertions, and call out any tests
|
|
that ARE well-targeted. Do not edit the files — read-only review.
|
|
setup:
|
|
files:
|
|
- path: "package.json"
|
|
source: "fixtures/jest-shallow/package.json"
|
|
- path: "src/order.ts"
|
|
source: "fixtures/jest-shallow/src/order.ts"
|
|
- path: "tests/order.test.ts"
|
|
source: "fixtures/jest-shallow/tests/order.test.ts"
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(shallow|trivial|toBeDefined|toBeTruthy|not\\.toBeNull|weak|low.*depth)"
|
|
- type: "output_matches"
|
|
pattern: "(always.*true|true.*true|tautolog)"
|
|
- type: "output_matches"
|
|
pattern: "(await|missing.*await|\\.resolves|async|silently.*pass)"
|
|
- type: "output_matches"
|
|
pattern: "(identity|same|self.compar|toBe\\(.*\\.id\\)|o\\.id.*o\\.id)"
|
|
- type: "exit_success"
|
|
rubric:
|
|
- "Identified Jest/TS-specific patterns correctly (did NOT mention MSTest/xUnit APIs as if present)"
|
|
- "Flagged the cluster of toBeDefined / toBeTruthy / not.toBeNull / Array.isArray assertions as trivial / low-depth"
|
|
- "Flagged the `expect(true).toBe(true)` always-true assertion"
|
|
- "Flagged the missing `await` on `expect(Promise.resolve(...)).resolves.toBeDefined()` as a silent-pass smell that lets rejections slip through"
|
|
- "Flagged `expect(o.id).toBe(o.id)` as an identity / self-comparing assertion that proves nothing"
|
|
- "Flagged `expect(o.id).not.toBe('totally unrelated string')` as a vacuous negative assertion"
|
|
- "Acknowledged 'legitimate equality on returned customer' (toBe('alice')) as a well-targeted assertion"
|
|
- "Acknowledged 'legitimate exception assertion' (toThrow('customer is required')) as a well-targeted assertion"
|
|
- "Recommended concrete higher-value assertions: verifying status='pending', itemCount, totalCents, id format, list() contents after multiple creates"
|
|
reject_tools: ["bash", "edit", "create"]
|
|
timeout: 180
|
|
|