Commit Graph

67 Commits

Author SHA1 Message Date
Amaury Levé 49a77a90bf code-testing-agent: add polyglot pipeline examples for Python/TypeScript/Go/Java (#708)
* code-testing-agent: add polyglot pipeline examples for Python/TypeScript/Go/Java

The code-testing-agent skill family is polyglot in description but in
practice biased toward .NET because dotnet-examples.md was the only
filled-in pipeline walkthrough. The four sub-agents that participate in
the Research-Plan-Implement pipeline (researcher, planner, implementer,
generator) all pointed to dotnet-examples.md whenever they suggested a
concrete example, which made it harder for the agent to produce
idiomatic non-.NET tests (e.g. in msbench top5-* benchmarks for
Python/Flask, TypeScript/Express).

This change

* adds four new example files mirroring dotnet-examples.md format
  (source → research → plan → generated test → fix cycle → final report):
  - python-examples.md (pytest, unittest.mock, Mock(spec=...), parametrize)
  - typescript-examples.md (Vitest with notes for Jest; it.each,
    async tests, fake timers, ESM/CJS fix cycle)
  - go-examples.md (standard testing package, table-driven subtests,
    hand-written fake repository, injected clock)
  - java-examples.md (JUnit 5 + Mockito on Maven, @ParameterizedTest +
    @CsvSource, Clock.fixed, Surefire fix cycles)
* updates code-testing-extensions/SKILL.md TOC to list the new files
  and clarifies usage instructions to read the matching <language>-
  examples.md alongside the base extension
* makes the "Concrete example" pointers in code-testing-generator,
  code-testing-implementer, code-testing-planner and
  code-testing-researcher agents language-agnostic (list all available
  example files instead of hard-coding dotnet-examples.md)
* expands code-testing-researcher project-structure detection list to
  cover more Python (tox.ini, noxfile.py, requirements*.txt, uv.lock,
  poetry.lock, pdm.lock), JS/TS (.mts/.cts/.jsx, vitest.config.*,
  jest.config.*), C++ (CMakeLists.txt, BUILD.bazel, meson.build),
  Java/Kotlin (pom.xml, build.gradle[.kts], wrappers), and other
  ecosystem files; expands the Identify-Language section accordingly
* extends the "Language-Specific Examples" section in
  code-testing-agent/SKILL.md to summarise each example file

Validated with: skill-validator check --plugin ./plugins/dotnet-test
(23 skills, 11 agents — all checks passed) and markdownlint-cli2.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review feedback for #708

- go-examples.md: replace the hand-rolled `contains`/`stringIndex`
  helpers with `strings.Contains` from the standard library. The hand-rolled
  `contains` had subtly wrong semantics — `contains(""abc"", """")` returned
  `false` while `strings.Contains` returns `true` — and the helpers are
  unnecessary complexity for a code-generation example.
- go-examples.md: in the `go test -run` "wrong selection regex" sample fix
  cycle, quote the test name and use `single_item` (matching the underscore
  that the surrounding diagnosis text refers to) instead of the unquoted
  `single item` which the shell would parse as two separate CLI arguments.
- java-examples.md: the source-tree file list described `Invoice.java` as a
  `record` but the `InvoiceService.markAsPaid` example mutates the invoice
  via `setStatus(...)` and `setPaidDate(...)` — records are immutable, so
  the description was internally inconsistent. Re-describe it as a mutable
  POJO with explicit mutators to match the service code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-02 13:42:46 +00:00
Amaury Levé 680292e04c Make dotnet-test analysis skills and auditor agent polyglot (#707)
* 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>
2026-06-01 16:46:26 +02:00
Amaury Levé 2b7fcdd7ab dotnet-test: add Rule #0 (Confirm the Test Target) to ruby/powershell extensions (#702)
* dotnet-test: add Rule #0 (Confirm the Test Target) to ruby/powershell extensions

When the prompt does not name a specific file ("test the repository", "one
core module", "comprehensive suite"), agents frequently target the wrong
code — typically the largest upstream module that already has rich existing
tests — instead of the newly-added module the user actually wants tested.
Recent benchmark runs (top5-{ruby,powershell}-*-{simple,complex}) showed
this is a dominant failure mode for Ruby/PowerShell: the agent burns 50+
turns writing tests for files the verifier never measures, while the real
target (a small untracked `lib/string_utils.rb` or `tools/StringUtils.psm1`)
sits one `git status` away.

Adds a Rule #0 to both ruby.md and powershell.md, ahead of the existing
"Rule #1: Investigate the Repo First". The rule:

- Tells the agent to use git history (`git status -s`,
  `git ls-files --others --exclude-standard`,
  `git log --diff-filter=A --name-only -5`) to find the actual target
  rather than guessing from repo size.
- Documents a Test Placement Contract — RSpec scopes to `spec/`,
  Pester scopes to whatever directory the harness passes to
  `Invoke-Pester -Path`; tests placed elsewhere are invisible.
- Adds a First-Test Sanity Loop: write one test, run --dry-run /
  -PassThru to confirm discovery > 0, fix LoadError / Import-Module
  issues before expanding. Catches placement mistakes on turn 1.

Both files validate cleanly under skill-validator. The existing Rule #1
and all subsequent sections are unchanged — this is a pure prepend.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Address PR review: clarify Rule #0 precedence and broaden require regex

- Rephrase Rule #0's discovery preamble in ruby.md and powershell.md to
  call out the commands as the read-only exception to Rule #1, removing
  the apparent contradiction between 'before planning' and Rule #1's
  'before writing any test or running any command'.
- Broaden the spec_helper require grep to match leading whitespace and
  `require_relative`, avoiding false negatives that send the agent to
  the wrong target.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-01 10:22:38 +02:00
Amaury Levé 3123e607a1 dotnet-test: add explicit non-.NET guards to 5 skill descriptions (#705)
* dotnet-test: add explicit non-.NET guards to 5 skill descriptions

Five skills in plugins/dotnet-test have language-neutral trigger phrases
in their USE FOR sections that could plausibly mis-route on non-.NET
prompts in mixed-language workflows:

- writing-mstest-tests ("write unit tests for a class", "create test class")
- test-anti-patterns ("audit my tests", "test smell audit")
- assertion-quality ("identify assertion-free tests")
- test-gap-analysis ("find weak tests", "discover untested edge cases")
- test-tagging ("categorize, audit, or label tests with traits")

Each skill now has an explicit non-.NET exclusion clause in its
DO NOT USE FOR section, naming the most common languages it must NOT
match (Python, JS/TS, Go, Java, Rust, Ruby, PHP, Swift, Kotlin) and
restating that the skill only handles C#/F#/VB.NET test code.

This was surfaced by an MSBench investigation comparing a baseline
Copilot CLI run vs the same run with this pruned dotnet-test plugin
installed against the sweatlas-tw-unit benchmark (24 Python / 15 Go /
5 TS, 0 .NET). Both runs scored identically (15/44 resolved). Skills
correctly never fired (0 invocations across all 43 instances), so this
is a hardening change, not a bug fix — it makes the router's job easier
in heterogeneous repos and future benchmarks.

Validated with: dotnet run --project eng/skill-validator/src/SkillValidator.csproj -- check --plugin plugins/dotnet-test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-01 10:21:13 +02:00
Amaury Levé 4f78daf583 run-tests: add platform-detection keywords for activation (#700)
* run-tests: add platform-detection keywords for activation

The 'Detect test platform from Directory.Build.props' eval scenario
regressed from 2.7/5 to 2.0/5 with run-tests not activated (skill
loaded column shows NOT ACTIVATED). The scenario prompt asks 'figure
out which test platform it uses' but the previous description framed
detection only as 'chooses the correct platform/SDK/framework syntax'
and 'selecting VSTest vs Microsoft.Testing.Platform command syntax' --
both focused on syntax selection, not on platform detection from
project files.

Per InvestigatingResults.md guidance for 'skill not activated'
failures, surface the detection use case explicitly with the file
names the scenario hinges on:

  detecting test platform/framework from \global.json\, \.csproj\,
  \Directory.Build.props\

Trim the syntax clause ('command syntax' -> 'syntax', 'including' ->
'incl.') and shorten the multi-TFM example (drop redundant
\dotnet test\ prefix) to stay under the 1,024-char description cap.

Folded description: 948 -> 1,010 chars.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* run-tests: rephrase platform detection with prompt-shaped language

The previous fix (021b0a343) activated the Detect test platform from
Directory.Build.props scenario in isolated mode but plugin-mode activation
still failed (1.3/5 → 1.7/5, isolated ✅ / plugin ⚠️ NOT ACTIVATED).

The scenario prompt asks the agent to `figure out which test platform`
a project uses, but the description used `detecting test
platform/framework` — the router did not bridge these phrasings when
competing sibling skills were loaded in plugin mode.

Changes:

- Replace `detecting test platform/framework from \global.json\...\` with
  `figuring out which test platform (VSTest vs Microsoft.Testing.Platform)
  a project uses from \global.json\, \.csproj\, \Directory.Build.props\
  and selecting the matching syntax\\. This mirrors the prompt verb
  `figure out\\ and merges the two adjacent clauses (detection +
  selection) into one stronger USE FOR entry.

- Trim verbose tokens elsewhere to stay within the 1024-char folded
  description cap (\SkillProfiler.cs\ MaxDescriptionLength): `TRX and
  other reporting` -> `TRX/reporting`, `writing or generating` ->
  `writing/generating`, `CI/CD pipeline configuration` -> `CI/CD
  config`, drop `e.g., ` from the VSTest/MTP mixups list.

Folded description length: 1010 -> 1007 / 1024.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* run-tests: lead description with platform detection as primary value

Plugin-mode activation still failed after the second iteration (2.0/5 →
2.3/5, isolated activates / plugin does NOT). Eval artifact analysis
(run 26581320083) shows the plugin agent actually correctly read
`Directory.Build.props` and identified MTP (rubric: 5/5 + 5/5 on
detection), but did NOT load the skill — so it missed the SDK 9 MTP
`--` separator rule and integration-test filtering (rubric: 1/5 + 1/5
on syntax), capping the score at 2/5.

The router declined to load the skill because the prior opening
sentence `Runs .NET tests with \dotnet test\ and chooses the correct
platform/SDK/framework syntax\\ sounded like base knowledge — the model
felt it could answer `run dotnet test` directly. The detection clause
was buried as the 2nd item in USE FOR, where the router did not weight
it strongly enough.

This rewrite leads the description with platform detection as the
primary value proposition:

  `For \dotnet test\: figures out which test platform (VSTest vs
  Microsoft.Testing.Platform) a project uses from \Directory.Build.props\,
  \global.json\, and \.csproj\, then picks the matching command
  syntax.\\

Other changes:

- Add a parallel USE FOR entry `identifying the test runner/platform
  from project files\\ to widen verb/noun coverage (`figures out` /
  `identifying`, `platform\\ / `runner`) for prompt phrasings the
  router may otherwise miss.

- Promote `\--\ separator rules on .NET SDK 8/9 vs 10+\\ from a
  parenthetical aside to a standalone USE FOR entry so it shows up as
  distinct specialized knowledge.

- Drop redundant `and selecting the matching syntax\\ since it is now
  in the opening sentence.

Folded description length: 1007 -> 994 / 1024. `skill-validator check`
green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 21:28:08 +02:00
Tom Longhurst 36209c3b52 TUnit Fixes & Improvements (#677)
* Update target framework to net10.0 and upgrade TUnit package to version 1.45.8

* Fix and expand TUnit coverage in dotnet-test-frameworks reference

Cross-referenced against tunit.dev/llms.txt and the official attributes
comparison page. Corrects the test class marker (TUnit is convention-based,
not [ClassDataSource]), and fills in the previously-missing TUnit rows for
the assertion APIs, setup/teardown methods, exception-handling examples,
and integration test category marker.

* Refine TUnit assertion table accuracy

The Type row's TUnit cell now uses IsAssignableTo<T>() to match the
assignable-type semantics of the MSTest/xUnit/NUnit equivalents, with a
note pointing at IsTypeOf<T>() for exact-type checks. The Skip row now
documents that [Skip] also applies at class and assembly scope and that
Skip.Test("reason") handles dynamic in-test skipping.

Verified against the TUnit migration guides and the type-assertions docs.

* Spell out TUnit assertion alternatives as complete awaited expressions

The Boolean, Null, Exception, and Type rows in the assertions table
previously used a `await Assert.That(x).IsTrue()` / `.IsFalse()` shorthand
for the alternative form. A reader copy-pasting just the second fragment
would end up with an un-awaited assertion that silently passes — which
contradicts the note immediately below the table about always awaiting.
Each alternative is now a complete, independently copy-pasteable expression.

Addresses the inline review on dotnet/skills#677.

---------

Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
2026-05-28 15:30:29 +02:00
Amaury Levé ac653c62e4 dotnet-test: add cross-language edit-boundary rules to code-testing-implementer (#689)
The code-testing-* agent family generates tests for 12 languages (not just
.NET). Until now, no instruction told the implementer to keep its changes
additive: it would routinely modify existing test files non-additively
(deleting/reformatting lines) or edit non-test production code to make
something easier to test. Both behaviors cause the change to be rejected
by:

- the msbench 'simple' test verifier (any 'dels > 0' on a test file, or
  any change to a non-test file, sets reward=0)
- most real-world test-quality gates, code-review policies, and CI

Add explicit cross-language rules in the implementer agent prompt:

1. Existing test files are append-only (no reformat/reorder/remove).
2. Do not modify non-test source files; surface untestable seams as
   follow-ups for the testability-migration agent.
3. Prefer new test files over edits to existing ones when equivalent.
4. Build-system manifests may be edited only for project/dependency
   registration.

Rule 6 in the Rules section now points at the Step 4 detail so the
implementer reads it on every phase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-27 09:42:22 +02:00
Amaury Levé ca21fd61c1 run-tests: prompt-shaped multi-TFM keywords for plugin activation (#688)
* run-tests: use prompt-shaped multi-TFM keywords for plugin activation

The 'Run tests in a multi-TFM project targeting a specific framework' eval

scenario kept failing plugin-mode activation after #667. The skill description

had 'multi-TFM projects (--framework)' as a brief parenthetical, but the

scenario prompt uses different language: 'This test project targets both

net8.0 and net9.0. I only want to run the tests on net9.0 using dotnet test.'

Per the InvestigatingResults.md guidance for 'skill not activated' failures,

expand that clause to include keywords from the prompt — 'running tests

against a single target framework when a project targets multiple TFMs'

plus a concrete '<TargetFrameworks>net8.0;net9.0</TargetFrameworks>' example

and the '--framework <TFM>' invocation. Per-skill description is 947 chars,

well under the 1024 spec cap.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Replace simple multi-TFM scenario with a harder MTP+SDK 9 variant that requires skill knowledge

The previous 'Run tests in a multi-TFM project targeting a specific
framework' scenario tested a trivial prompt (single --framework flag)
that the model already answers perfectly from training (baseline 4.7/5).
This matches pattern #8 (baseline already good, no headroom) in
InvestigatingResults.md, and explains why two prior attempts to fix
plugin-mode activation via description tweaks (PR #667, #688) failed:
the router rationally skips loading the skill for a trivial question.

This change replaces the scenario with a meaningfully harder one that
combines several signals the model often confuses:

  - Multi-TFM project (TargetFrameworks plural)
  - MTP runner (TestingPlatformDotnetTestSupport)
  - .NET SDK 9 (-- separator required for MTP extension args)
  - TRX report (MTP extension flag)

The correct answer requires knowing that --framework is a dotnet
test/MSBuild flag that always goes BEFORE --, while --report-trx is an
MTP extension flag that goes AFTER -- on SDK 9:

  dotnet test --framework net9.0 -- --report-trx

The ordering assertion in eval.yaml enforces this on a single line, so
swapping --framework after the separator no longer satisfies the
scenario.

Also fix a documentation bug in SKILL.md surfaced by this work: the
'Common MTP flags > Built-in flags' table previously listed --framework
and --no-build under 'On SDK 8/9, pass after --', which is wrong. Those
are dotnet test/MSBuild flags consumed by dotnet test itself; they
always go before --. The table now lists only flags genuinely consumed
by MTP, and an Important note clarifies the rule.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 17:57:21 +02:00
Amaury Levé 5810d492c9 test-anti-patterns / test-smell-detection: narrow-specialist re-pitch (Variant B) (#671)
Both skills suffer plugin-mode activation failures: in plugin runs the model

bypasses the skill tool entirely for ~5/6 of test-anti-patterns audit prompts

and ~2/3 of test-smell-detection prompts, answering directly from training.

Variant B repositions the two skills as umbrella + narrow specialist:

* test-anti-patterns becomes THE umbrella audit skill for all pragmatic

  test-quality reviews (anti-patterns and smell-style prompts alike). Its

  description explicitly absorbs smell-audit triggers.

* test-smell-detection is repositioned as a narrow niche that only fires

  when the user explicitly asks for the testsmells.org / academic 19-smell

  catalog with citable smell names from the research literature.

Eval prompts for test-smell-detection are rewritten to match the narrow

niche (explicit testsmells.org / 19-smell catalog requests) so we test

specialist activation rather than the umbrella scenarios.

Variant B of a 3-PR experiment to fix activation. Companion PRs:

* Variant A = activation-only rewrite, both skills keep overlap;

* Variant C = full merge into test-anti-patterns.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-25 13:18:17 +00:00
Amaury Levé 362b3f25ec Fix plugin-mode skill activation for 8 dotnet-test scenarios (#667)
* migrate-vstest-to-mtp: fix plugin activation for OutputType=Exe scenario

The `Set OutputType=Exe only for test projects in Directory.Build.props`
scenario was failing plugin-mode skill activation (skillActivationPlugin.
activated=false, detectedSkills=[]) in the latest scheduled eval. The
model answered from its own knowledge and proposed the wrong solution
(`Condition="'$(IsTestProject)' == 'true'"` in Directory.Build.props,
which the skill explicitly warns against).

Two fixes:

1. SKILL.md description: add an explicit `conditioning OutputType=Exe to
   test projects when centralizing MTP properties in Directory.Build.props`
   USE FOR clause so the description surfaces this specific MTP migration
   pitfall to the skill router. Per-skill description stays at <= 1024
   chars (trimmed `configuration` -> `config` and `MSTest version
   upgrades (use migrate-mstest-* skills)` -> `MSTest version upgrades`
   to keep within the spec limit).

2. eval.vally.yaml: add the missing scenario (the eval.yaml scenario was
   added in PR #556 but vally was never synced — vally had 10 stimuli vs
   eval.yaml's 11). Brings vally and skill-validator coverage to parity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test-anti-patterns: strengthen description for severity-ranked audits

The `Detect mixed severity anti-patterns in repository service tests`
scenario was failing plugin-mode skill activation
(skillActivationPlugin.activated=false, detectedSkills=[]) in the latest
scheduled eval, even though the prompt explicitly says `Audit the test
class ... for .NET test anti-patterns ... Give me a severity-ranked
list (Critical / Warning / Info)`.

The previous description only mentioned `USE FOR: audit test quality,
review test code, find test anti-patterns, ...`, so the model could not
distinguish this skill from sibling test-quality skills based on the
`severity-ranked` and `Critical/Warning/Info` framing in the prompt.
Surface the catalog shape (severity-ranked output, concrete code-level
fixes) and add explicit `severity-ranked test audit`, `self-comparing
assertions` and `broad exception types` triggers — these are the
exact phrases used by failing scenarios.

Description stays at 822 chars (<= 1024 limit). Aggregate dotnet-test
description stays at 15,099 chars (<= 20,000 limit).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* run-tests: restructure description for higher-signal plugin activation

Six run-tests scenarios were failing plugin-mode skill activation in the
latest scheduled eval (skillActivationPlugin.activated=false,
detectedSkills=[]) even though isolated activation worked for every
scenario:

- Run tests with trx reporting on MTP project (SDK 9)
- Run tests in a multi-TFM project targeting a specific framework
- Filter MSTest tests by category on VSTest
- Filter NUnit tests by class name on VSTest
- Filter TUnit tests by class using treenode-filter
- Negative test: do not use MTP syntax for a VSTest project

The previous description piled ~30 quoted trigger phrases (`run tests`,
`run my tests`, `run these tests`, `execute tests`, `dotnet test`,
`test filter`, `filter by category`, `filter by class`,
`combine filters`, `run only specific tests`, `integration tests`,
`unit tests`, `tests not running`, `hang timeout`, `blame-hang`,
`blame-crash`, `crash dump`, `TRX report`, `TRX`, `test report`,
`generate TRX`, `TUnit`, `treenode-filter`, `target framework`,
`multi-TFM`, ...). In plugin mode this signal-poor keyword wall made
the skill look generic enough that the router preferred to answer
directly from model knowledge.

Replace the keyword pile with five higher-signal scope clauses grouped
by user-visible concern:

1. running, filtering, or troubleshooting `dotnet test`
2. VSTest vs Microsoft.Testing.Platform syntax (incl. `--` separator
   rules on SDK 8/9 vs 10+)
3. framework-specific filter syntax for MSTest / xUnit / NUnit / TUnit
   (--filter, --filter-class, --filter-trait, --filter-query,
   --treenode-filter)
4. TRX/reporting (--report-trx vs --logger trx), blame/hang/crash
   diagnostics, multi-TFM (--framework)
5. avoiding MTP/VSTest argument mixups

These are the same concerns the previous description tried to cover,
but framed as decisions the skill helps make (and that distinguish it
from sibling test skills) rather than as a list of bare keywords.
Per-skill description shrinks from 1,000 to 819 chars (still <= 1,024
limit). Aggregate dotnet-test description stays well under the
20,000-char cap.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test-anti-patterns: drop specific severity labels from description

PR review (copilot-pull-request-reviewer on #667) caught that
`Produces a severity-ranked (Critical / Warning / Info) catalog ...`
in the new description contradicts the SKILL.md body, which actually
teaches a 4-level Critical / High / Medium / Low taxonomy. The
`Critical / Warning / Info` wording came from one eval scenario's
prompt, but other prompts ask for different bucket schemes, and the
skill itself does not enforce a fixed three-level mapping.

Drop the specific labels from the description and keep just
`severity-ranked` as the activation signal. The body remains
unchanged (it teaches Critical / High / Medium / Low and the agent
maps to the prompt's requested buckets at output time).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 13:44:40 +02:00
Amaury Levé b24599aa36 test-smell-detection: trim to detailed tier and add prompt-shaped triggers (#653)
Multi-model skill-validator eval (claude-haiku-4.5, claude-opus-4.6,

gpt-5.3-codex, gpt-5.4-mini) showed two issues with this skill:

1. Quality regression on stronger models (+0.15 haiku, -0.14 opus,

   -0.17 codex, -0.29 gpt-5.4-mini): the skill added tokens and tool

   calls without lifting rubric quality on larger models.

2. Plugin-mode activation loss: the skill activated reliably in

   isolated mode but was almost never picked in plugin mode where it

   competed with siblings (code-testing-agent, etc.).

Changes:

- Trim BPE tokens 2,487 -> 1,472 (still detailed tier, well within

  the 800-2,500 sweet spot per SkillsBench guidance). Collapsed long

  smell-by-smell prose, `Why Test Smells Matter`, and pitfalls into a

  compact taxonomy table plus a short decision procedure / output

  checklist. Removed bulky examples. Kept taxonomy, calibration,

  negative guidance, and references intact.

- Add prompt-shaped USE FOR triggers drawn from the eval prompts

  (`review test smells`, `review these tests and tell me if there are`

  `any problematic patterns`, `check my tests for test design`

  `problems or anti-patterns`, `give us an objective assessment of`

  `our integration tests`, plus explicit smell names).

- Strengthen DO NOT USE FOR clause: `write new tests / scaffold tests`

  `from scratch / generate a complete MSTest test suite` now defers

  cleanly to code-testing-generator (covers the negative eval scenario).

Validation: skill-validator check --plugin clean for this skill;

build + 545/545 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 13:42:13 +02:00
Jan Krivanek 2fcfc099b9 Improve direct scenario (#675) 2026-05-19 19:34:29 +02:00
Amaury Levé dde9f99cf0 dotnet-test: drop tools field from agents that declared it (#665)
The four agents (code-testing-generator, test-migration, testability-migration,
test-quality-auditor) were the only dotnet-test agents declaring a 'tools:'
list. Per Jan's suggestion on #660, drop the field so they inherit the runtime's
default tool surface (matching the convention used by every other agent in the
repo).

Follow-up to #660.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 14:47:00 +02:00
Amaury Levé 2a193300ca Replace 'terminal' with 'bash' and 'powershell' in agent tools (#660)
The skill-validator only recognizes 'bash' and 'powershell' as built-in shell tools, not 'terminal'. Update the four affected agents in the dotnet-test plugin to use both for cross-platform support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 13:39:33 +02:00
Amaury Levé b0c2336d49 Tighten crap-score boundary to fix coverage-analysis plateau activation (#652)
Dashboard data showed coverage-analysis failing to activate in 8/10
recent scheduled plugin-mode runs for the 'Coverage plateau diagnosis'
scenario, while activating reliably in isolated mode. PR #647 added
positive triggers to coverage-analysis but did not address sibling
attention competition.

The crap-score description matched the plateau prompt almost as well as
coverage-analysis (it advertised 'evaluate whether complex methods have
sufficient test coverage' + 'Requires code coverage data (Cobertura
XML)') without redirecting project-wide / stuck-coverage diagnosis to
coverage-analysis. With 22 sibling skills competing for attention this
overlap is enough to suppress activation altogether.

Tighten the crap-score frontmatter to:
- Scope positive triggers to a named method, class, or single source
  file (the actual eval surface — see tests/dotnet-test/crap-score/
  eval.yaml, all 3 scenarios target OrderService.cs).
- Add explicit DO NOT USE FOR redirects covering project-wide coverage
  analysis, coverage plateau / stuck coverage, what's blocking
  coverage, and where to add tests across a project — all of which
  point at coverage-analysis.

skill-validator check passes (22 skills, 11 agents, 1 plugin).
Aggregate dotnet-test description size: 14,932 chars (limit 15,000).
markdownlint passes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-15 16:24:10 +02:00
Amaury Levé 3d59e44c7e Fix coverage-analysis activation for plateau diagnosis prompts (#647)
* Fix coverage-analysis activation for plateau diagnosis prompts

coverage-analysis SKILL.md:
- Trim verbose implementation details (provider detection,
  ReportGenerator) that consumed description budget without
  aiding skill activation
- Add explicit USE FOR keywords: coverage stuck, coverage plateau,
  can't increase coverage, what's blocking coverage

code-testing-agent SKILL.md:
- Add 'diagnosing coverage plateaus or CRAP score computation
  (use coverage-analysis)' to DO NOT USE FOR boundary to prevent
  test-generation skill from intercepting diagnostic prompts

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Strengthen code-testing-agent activation; harden coverage-analysis isolated mode

Address eval regressions reported on PR #647 (run 25813728646):

1. code-testing-agent: `Generate tests for ContosoUniversity ASP.NET Core MVC app`
   was NOT ACTIVATED in plugin mode (detectedSkills=[], skillEventCount=0,
   invokedAgents=[]). The model bypassed the skill system entirely.

   - SKILL.md description: restructure to use the proven `Use when user says ...`
     pattern with quoted trigger phrases (matching the run-tests skill that
     consistently activates), make the link to the code-testing-generator
     sub-agent explicit, and tighten DO NOT USE FOR clauses.
   - eval prompt (eval.yaml + eval.vally.yaml): make the request
     pipeline-shaped (`project-wide, multi-file test generation task`,
     `scaffold a new test project`) so the model recognizes it as multi-step
     work that benefits from the orchestrated pipeline. Explicitly request
     coverlet.collector + a Cobertura XML run so rubric criterion 1
     (`high line coverage as reported by the Cobertura XML in TestResults/`)
     becomes achievable without overfitting.

2. code-testing-tester agent + code-testing-extensions/dotnet.md: open a
   scoped exception to the `skip coverage tools` rule. Default behavior
   stays the same, but when the user/harness explicitly asks for a
   Cobertura/XML coverage artifact, the agent may add coverlet.collector
   to the generated test csproj so the harness's coverage command produces
   output. The agent still does not run the coverage command itself.

3. coverage-analysis SKILL.md: add a `User-visible output is mandatory`
   guard at the top of the Workflow section. The latest eval showed isolated
   mode producing literally `(no output)` in 2 of 3 scenarios — the agent
   ran Compute-CrapScores.ps1 / Extract-MethodCoverage.ps1 / ReportGenerator
   in parallel, then the session ended without ever surfacing findings.
   The guard tells the agent to always return a partial summary instead of
   ending silent, and to deprioritize ReportGenerator HTML when budget is
   tight. (Plugin-mode quality is already strong: 4.3 / 4.3 / 5.0 — no
   regression risk there.)

Aggregate dotnet-test plugin description size: 14,925 chars (limit 15,000).
skill-validator check passes (22 skills, 11 agents, 1 plugin); markdownlint
passes for all 4 modified files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Restore MSTest modernization exclusion in code-testing-agent description

* Fix isolated-mode coverage-analysis: emit summary before optional ReportGenerator

The previous workflow encouraged the agent to run `dotnet tool install` for
ReportGenerator in parallel with the CRAP scoring scripts (Phase 2 "Steps
3 and 4 in parallel" + Phase 3 "Steps 5 and 6 in parallel"). In isolated
mode that pattern reliably crashed the session with "Failed to persist
session events: timeout while waiting for mutex to become available"
right after the scripts returned valid data, so the agent never produced
the user-facing summary.

Restructure the workflow into 5 phases:

- Phase 1 (Setup) - unchanged
- Phase 2 (Test execution) - skip when Cobertura XML already exists
- Phase 3 (Analysis) - run only the two PowerShell scripts, no RG
- Phase 4 (User-facing summary) - MANDATORY, must be the next assistant
  response after Phase 3, before any RG work; also save
  coverage-analysis.md as a secondary follow-up
- Phase 5 (ReportGenerator HTML/CSV) - strictly optional, post-summary,
  skipped by default for existing-Cobertura and plateau-diagnosis paths

Also update references/output-format.md so the Reports section marks RG
artifacts as "Not generated (optional - request HTML reports to enable)"
when Phase 5 has not run, and update references/guidelines.md so the
"show and open the markdown report" rule explicitly defers to the
user-facing assistant response.

Targets the isolated-mode regressions in PR #647 eval:
- Project-wide coverage with existing Cobertura: 1.0/5 -> expected 3+
- Coverage plateau diagnosis: 1.0/5 -> expected 3+
- Run coverage from scratch: 2.3/5 -> expected steady or up

Verified: skill-validator check --plugin ./plugins/dotnet-test passes;
markdownlint-cli2 clean on all 3 modified files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR #647 review comments

1. Prerequisites: distinguish the from-scratch path (needs NuGet for the
   coverage-provider package install + optional internet for ReportGenerator)
   from the existing-Cobertura path (needs neither).

2. Add Step 2c "Discover or accept existing Cobertura XML" so the
   existing-data path actually has $coberturaFiles populated before
   Phase 3, instead of relying on Phase 2's discovery (which it
   skips). Also clarify Step 2's destructive Remove-Item only manages
   the skill-owned coverage-analysis/ subdirectory.

3. references/output-format.md: replace the unconditional
   "Reports saved to: <coverageDir>/reports/" line with one that
   always points at <coverageDir>/ (markdown summary + raw Cobertura)
   and only mentions reports/ if Phase 5 ran.

4. Have Compute-CrapScores.ps1 emit OVERALL_LINE_COVERAGE and
   OVERALL_BRANCH_COVERAGE from the Cobertura root attributes, and
   update Phase 4 to read those values directly from the script's
   output. The Phase 4 mandatory-summary rule no longer requires a
   separate XML parse before composing the response.

Verified: skill-validator check --plugin ./plugins/dotnet-test passes;
markdownlint-cli2 clean on all modified files; Compute-CrapScores.ps1
smoke-tested on a synthetic Cobertura XML (emits OVERALL_LINE_COVERAGE:75,
OVERALL_BRANCH_COVERAGE:50 alongside HOTSPOTS).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Apply suggestion from @Evangelink

* Address unresolved coverage-analysis and eval review comments

* Refine follow-up review feedback from validation

* Tighten coverage aggregation fallback notes and counters

* Clarify pre-response save instruction wording

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+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>
2026-05-14 17:41:31 +00:00
Amaury Levé 42afc2688d Add Go, Java, Rust, Ruby, Swift, and Kotlin extensions to code-testing-extensions (#650)
* Add Go, Java, Rust, Ruby, Swift, and Kotlin extensions to code-testing-extensions

Adds six new language-specific guidance files to the code-testing-extensions skill, modeled on the existing python.md and typescript.md structure.

Each new extension covers: investigate-first rule, toolchain detection, build commands, test commands (with framework variants), lint command, project layout/imports, common errors with fixes, mocking rules, dependency installation as last resort, and a Skip Coverage Tools footer.

SKILL.md is updated to advertise the new files in the discovery table.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review feedback and fix markdownlint issues

- rust.md: replace #  code span (MD038) with quoted text

- java.md: clarify wildcard-import guidance to avoid contradicting the explicit-imports template

- java.md: scope 'class must be public' to JUnit 4 only (JUnit 5 allows package-private)

- java.md: correct Mockito final-class fix to inline mock maker (default in 5+, mockito-inline for 3.x/4.x); remove incorrect mockito-subclass suggestion

- kotlin.md: same Mockito final-class correction

- kotlin.md: replace nonexistent testScheduler.testDispatcher() with StandardTestDispatcher(testScheduler)

- kotlin.md: rephrase coroutines-test dependency guidance to avoid contradiction

- kotlin.md: correct cross-module 'internal' fix; @VisibleForTesting does not widen Kotlin visibility

- ruby.md: replace numbered block parameter '_1' with '|f| require f' (works on Ruby < 2.7)

- swift.md: Swift Testing requires Swift 6/Xcode 16, not 5.10

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-14 17:51:27 +02:00
Amaury Levé f532cf1d94 Add coverage-touching and self-referential assertion heuristics (#635)
* Add coverage-touching and self-referential assertion heuristics

- test-anti-patterns: add 'Coverage touching' and 'Self-referential assertion'
  as named Critical-severity anti-patterns in the detection catalog
- assertion-quality: add 'Tests with self-referential assertions' metric and
  a calibration rule distinguishing tautological from valid round-trip assertions
- Add eval scenarios for both new heuristics in test-anti-patterns (coverage-
  touching ProductCatalog facade, self-referential SerializerTests)
- Add eval scenario and fixture for self-referential assertions in
  assertion-quality (ConfigTests with identity/round-trip patterns)

* Fix test-anti-patterns activation: rewrite description with USE FOR keyword list

The skill was not activating in any eval scenario because the description
used narrative prose instead of the explicit 'USE FOR:' / 'DO NOT USE FOR:'
keyword list pattern that well-activating sibling skills use (run-tests,
writing-mstest-tests). Restructured the description with trigger phrases
matching common user prompts.

* Fix eval activation, timeouts, and add missing vally scenarios

- test-anti-patterns/eval.vally.yaml: increase timeout 2m→5m, add
  coverage-touching and self-referential scenarios with constraints
- assertion-quality/eval.vally.yaml: add self-referential scenario
  with environment files, broaden assertion pattern
- test-anti-patterns/eval.yaml: add setup.files to all 6 scenarios
  to create workspace files that trigger skill discovery/activation
- assertion-quality/eval.yaml: increase timeouts 120→300 for
  self-referential and decline-request scenarios, broaden
  self-referential assertion pattern
- Create fixture files for mixed-severity, well-written,
  coverage-touching, and self-referential test-anti-patterns scenarios

* Address review comments: fix test names and use source references

- Rename ThrowsArgumentException to ThrowsArgumentOutOfRangeException in
  PaymentProcessorTests.cs fixture and inlined code in eval.yaml and
  eval.vally.yaml to match the actual exception type being asserted.
- Replace inline csproj content blocks with source references to existing
  fixture files for UserRepo, Payments, and CatalogService scenarios in
  eval.yaml to avoid drift between fixtures and eval setup.

* Address review comments: pin MSTest versions, use source refs, fix naming

- Pin MSTest to 3.8.2 in all fixture .csproj files, add standard
  properties (ImplicitUsings, Nullable, IsPackable)
- Replace inline csproj content blocks with source references to
  fixture files to avoid content drift
- Create missing .csproj fixtures for flaky-coupled, duplicate-magic,
  and assertion-quality self-referential scenarios
- Fix test method names: ThrowsArgumentException ->
  ThrowsArgumentOutOfRangeException to match the actual assertion

* Fix activation, eval timeouts, and per-skill description limits

Address remaining issues from PR #635 eval scoreboard
(run 25677669933) and skill-validator failures:

1. test-anti-patterns activation (was NOT ACTIVATED in BOTH plugin and
   isolated mode for ALL 6 scenarios — model answered everything from
   inline code without ever needing the skill):

   - eval.yaml + eval.vally.yaml: drop the giant inline `csharp` blocks
     from every prompt. Each prompt now names the workspace files
     explicitly (`Audit `Foo.Tests/FooTests.cs` for .NET test
     anti-patterns ...`) and asks for the skill's signature deliverable
     (severity-ranked list with concrete code-level fixes). The model
     must read the workspace, which gives it a chance to consult the
     skill — and the skill's structured-findings format is the actual
     value-add over inline analysis.
   - All 6 scenarios consistently get reject_tools (read-only review)
     and timeout 180s.
   - eval.vally.yaml: also added missing environment.files for each
     scenario (was prompt-only before, no fixture on disk).

2. assertion-quality `Flag assertion-free tests` plugin-mode activation
   (was bouncing to other skills because the prompt was generic `check
   whether these tests verify anything useful`):

   - eval.yaml + eval.vally.yaml: rewrite the prompt to name the file
     (`SmokeTests/ApiEndpointSmokeTests.cs`) and explicitly request
     `assertion quality and depth`, `assertion-free tests`, and
     `trivial assertions like Assert.IsNotNull` — direct trigger
     phrases for assertion-quality.
   - assertion-quality SKILL.md: extend description with explicit USE
     FOR keywords for `assertion-free tests`, `self-referential`, and
     `tautological` so plugin-mode activation isn't won by sibling
     skills like test-anti-patterns.

3. test-anti-patterns description size — was 1,301 chars (over the
   1,024 per-skill limit) AND pushed dotnet-test plugin aggregate to
   15,312 (over the 15,000 limit), failing skill-check on PR #635.
   Trimmed to 779 chars; aggregate now at 14,983.

4. Vally job-level timeout (60m → 180m) was already raised on main
   in commit 0f31228b5 (#641); inheriting that via merge of upstream/main.

Verified: skill-validator check --plugin passes (22 skills, 11 agents,
1 plugin); markdownlint clean; all 4 eval YAMLs parse OK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address round-2 review comments: add missing production stubs, reject_tools

Address the 3 new Copilot review comments on PR #635
(IDs 3240547649, 3240547701, 3240547725):

1. coverage-touching fixture: `ProductCatalogTests.cs` references
   `new InMemoryStore()` but the fixture only declared the
   `IProductStore` interface. Audit agents could surface `this won't
   compile` as the top finding instead of the intended coverage-touching
   pattern. Added a minimal `InMemoryStore : IProductStore`
   implementation in the same file as `ProductCatalog.cs`.

2. self-referential fixture: `SerializerTests.cs` referenced 8 production
   types (Serializer, UserDto, Money, Config, NameNormalizer, Mapper,
   UserEntity, Validator) with no production code on disk. Added a new
   `Serialization/Serialization.cs` file with minimal stubs for all 8
   types so the audit can stay focused on assertion semantics. Updated
   the `Detect self-referential...` scenario in eval.yaml +
   eval.vally.yaml to copy the new file into the workspace.

3. assertion-quality `Identify self-referential assertions...` scenario:
   added `reject_tools: [bash, edit, create]` and explicit `Do not
   edit the files` wording to match the read-only audit pattern used by
   other scenarios in the file. Applied to both eval.yaml and
   eval.vally.yaml (where it lives under `constraints.reject_tools`).

Verified: skill-validator check passes, markdownlint clean, all 4
eval YAMLs parse OK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Strengthen activation: name anti-patterns explicitly, dedupe self-referential boundary

PR #635 eval scoreboard run [25859929883](https://github.com/dotnet/skills/actions/runs/25859929883):
- 3 test-anti-patterns scenarios still NOT ACTIVATED in plugin mode (mixed
  severity, flakiness, well-written) — variance was high (CV 0.90-1.59),
  but only 1-3 of 9 plugin runs actually loaded the skill, vs 3/3 for
  scenarios that named specific patterns (coverage-touching, self-referential).
- assertion-quality 'Identify self-referential' NOT ACTIVATED in plugin —
  detectedSkills was empty (model picked neither AQ nor TAP despite both
  matching the prompt's 'self-referential or tautological' phrasing).

Two-pronged fix:

1. Reduce overlap between assertion-quality and test-anti-patterns —
   remove 'self-referential or tautological assertions' from
   test-anti-patterns USE FOR. Both skills could plausibly own this, but
   assertion-quality is the more focused owner; in plugin mode neither
   was winning, so giving assertion-quality the unambiguous trigger
   improves activation. test-anti-patterns still owns the broader 'tests
   pass but don't verify anything', and the test-anti-patterns 'Detect
   self-referential' eval scenario activates fine on the explicit
   'audit ... for .NET test anti-patterns' phrasing.

2. Strengthen the 5 problem prompts with skill-specific terminology —
   the working pattern from coverage-touching/self-referential prompts
   (3/3 and 2/3 plugin activation) was naming the specific anti-pattern
   category. Apply the same pattern to the failing scenarios:
   - test-anti-patterns/Detect mixed severity: enumerate the catalog
     (missing/no assertions, swallowed exceptions, always-true /
     self-comparing, weak negative, broad exception types, unused
     fields) and ask for findings tied to named anti-patterns.
   - test-anti-patterns/Detect flakiness: name the pattern categories
     explicitly (Thread.Sleep / DateTime.Now flakiness, ordering
     dependency, shared static state, reflection coupling, god tests).
   - test-anti-patterns/Recognize well-written: enumerate the catalog
     and ask for severity-ranked output 'Critical / Warning / Info /
     no issues found' tied to named anti-patterns.
   - assertion-quality/Identify self-referential: ask for an
     'assertion-quality analysis' / 'assertion-quality metrics' /
     'assertion-quality review' (3 mentions of the skill name) and
     name the metric (how many tests are self-referential).

Same prompt updates applied to both eval.yaml and eval.vally.yaml.
skill-validator check passes (22 skills, 11 agents, 1 plugin),
aggregate description 14,938 / 15,000.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-14 17:43:35 +02:00
YuliiaKovalova e1e8568375 Revert "dotnet-test: add unit-under-test + behaviors quality cue to code-test…" (#651)
This reverts commit f1b09eba79.
2026-05-14 17:00:07 +02:00
Amaury Levé de0a97c551 Fix migrate-vstest-to-mtp activation for Handle exit code 8 scenario (#648)
The `Handle exit code 8 when migrating from VSTest to MTP` scenario was
not activating the migrate-vstest-to-mtp skill in plugin mode in the
latest scheduled eval (skillActivationPlugin.activated=false,
detectedSkills=[], skillEventCount=0, vally row showed `--`), even
though all 10 other scenarios in this eval activated cleanly.

Three layered fixes:

1. Prompt (eval.yaml + eval.vally.yaml): switch from past-tense
   `We migrated`/`How do I fix this behavioral difference` to
   present-tense migration framing — `We're migrating ... After
   enabling MTP ... How do I handle this MTP behavioral difference?`.
   The previous past-tense framing read as a generic post-migration CI
   troubleshooting question, which the model felt confident answering
   without consulting any skill.

2. SKILL.md description: add an explicit `USE FOR:` clause for MTP
   behavioral differences (exit code 8, zero tests discovered,
   --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE), matching the
   pattern that fixed coverage-analysis activation in 9fc75e2cd.
   Aggregate dotnet-test description size stays at 15,000 chars (limit).

3. SKILL.md `When Not to Use`: tighten `project already runs on MTP
   -- migration is done` so it no longer disqualifies post-enable
   behavioral-difference cases like exit code 8.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-14 11:29:59 +02:00
Amaury Levé 0f31228b58 Fix eval timeouts and skill activation for dotnet-test evals (#641)
* Fix evaluation timeouts and improve prompts for dotnet-test skills

- writing-mstest-tests: increase global vally timeout from 3m to 5m to match
  the 300s eval.yaml timeout for the complex 'Modernize legacy test patterns' stimulus
- code-testing-agent: increase timeout from 40m/2400s to 60m/3600s
- mtp-hot-reload: increase timeout from 6m to 10m and remove overly strict
  expect_tools constraint on launchSettings stimulus
- migrate-mstest-v1v2-to-v3: rephrase prompt for assertion overload errors to
  mention CS1501 and cover AreNotEqual/AreSame alongside AreEqual

* Increase eval timeouts for mtp-hot-reload and migrate-mstest-v1v2-to-v3 scenarios

* Strengthen activation prompts and add missing vally scenarios

- migrate-mstest-v1v2-to-v3: Add explicit 'MSTest v2 to v3' migration
  language in .testsettings and DataRow prompts (both eval.yaml and
  eval.vally.yaml)
- writing-mstest-tests: Add 'MSTest' keyword and skill-specific
  terminology to all prompts that lacked activation signal
- writing-mstest-tests: Add 5 missing vally scenarios (string
  assertions, comparison assertions, collection/null/reference
  assertions, conditional execution, parallelization)
- Add service-registry fixture files for the collection assertions
  scenario

* Improve skill activation via SKILL.md descriptions and prompt alignment

Three-pronged fix for systematic NOT ACTIVATED failures:

1. SKILL.md descriptions: Restructure writing-mstest-tests, migrate-
   mstest-v1v2-to-v3, and code-testing-agent descriptions to use the
   proven 'Use when user says' pattern with quoted trigger phrases
   (matching the working run-tests pattern)

2. Vally prompts: Each prompt now contains at least one exact quoted
   trigger phrase from its SKILL.md description to ensure strong
   description-to-prompt matching

3. Specific fixes:
   - writing-mstest-tests: All 15 prompts now include MSTest-specific
     trigger phrases (Assert.ThrowsExactly, sealed test class, DataRow,
     DynamicData, Assert.HasCount, Assert.IsInstanceOfType, etc.)
   - migrate-mstest-v1v2-to-v3: Add '.NET 5 dropped' and 'framework
     compatibility issues' to trigger phrases; strengthen dropped-TFM
     prompt
   - code-testing-agent: Add 'generate comprehensive unit tests' and
     'achieve high code coverage' to trigger phrases

* Revert SKILL.md description changes that caused activation regression

The description restructuring in 67056d8ec broke skill activation:
- migrate-mstest-v1v2-to-v3: went from 6/9 activating to 0/9
- writing-mstest-tests: lost isolated activation
- code-testing-agent: unnecessary change to working description

Restore all three SKILL.md files to their pre-regression state.
Keep the vally prompt improvements from 259727e.

* Fix writing-mstest-tests plugin-mode activation

- Add MSTest carve-out to code-testing-agent DO NOT USE FOR to prevent
  it from intercepting MSTest-specific prompts
- Add test parallelization/MSTest.Sdk keywords to writing-mstest-tests
  description (scenario 15 failed even in isolated mode)
- Strengthen prompts to be more MSTest-specific:
  - Scenario 1: emphasize MSTest patterns over generic 'write tests'
  - Scenario 4: remove vague 'something seems off', directly ask to
    fix swapped Assert.AreEqual arguments
  - Scenario 5: reframe as modernization request with specific APIs
  - Scenario 13: name specific MSTest assertion APIs in the prompt

* Fix writing-mstest-tests description over 1024 char limit

Shorten the USE FOR section by removing redundant 'help me write
comprehensive tests' and condensing the assertion API list.
Description is now 944 chars (limit: 1024).

* Increase vally job timeout from 60m to 180m

The code-testing-agent eval has a 60m per-stimulus timeout, and vally
runs multiple configurations (baseline, isolated, plugin). The 60m
job-level timeout was causing the job to be cancelled mid-evaluation.

Match the 180m timeout from the evaluate job in evaluation.yml.

* Address PR review comments

- Add IsPackable=false to writing-mstest-tests fixture csproj for
  consistency with other dotnet-test fixture projects
- Fix grammar in migrate-mstest-v1v2-to-v3 eval prompts: add comma
  after 'upgrade' and add 'file' for clarity (both eval.yaml and
  eval.vally.yaml)

* Trim dotnet-test aggregate description size under 15,000 limit

Consolidate duplicate filter keyword mentions in migrate-vstest-to-mtp
and shorten the cross-reference in migrate-xunit-to-xunit-v3 while
keeping the --filter-class/--filter-trait/--filter-query trigger
keywords for skill activation.

* Fix vally skill activation for 9 failing eval scenarios

Improve eval.vally.yaml prompts that were too specific, causing the model
to answer from general knowledge without activating the skill:

- migrate-mstest-v1v2-to-v3: Remove leading question that gives away the
  answer ('Is .NET 5 dropped?'); use multi-target fixture matching eval.yaml
- writing-mstest-tests (7 scenarios): Add 'following MSTest best practices'
  to trigger skill reading; make prompts more open-ended (don't name exact
  APIs like OSCondition, Assert.AreSame); match eval.yaml prompt style
- code-testing-agent: Clarify app complexity to encourage skill pipeline

The pattern: vally prompts that give away exact API names or answers let
the model skip reading the skill. More open-ended prompts referencing
'best practices' trigger skill activation.

* Improve skills and eval prompts for regression scenarios

migrate-xunit-to-xunit-v3 SKILL.md:
- Restructure from 16 steps to 13, merging redundant steps
- Move test platform selection from step 12 to step 4
- Mark steps 6-12 as conditional with prioritization note
- Remove external URL references that caused web_fetch detours

writing-mstest-tests SKILL.md:
- Add Response Guidelines for proportional responses
- Remove redundant Validation checklist and Common Pitfalls table
  (all items already covered in workflow steps)
- Reduces token count from 3,305 to 2,944

migrate-mstest-v1v2-to-v3 eval.vally.yaml:
- Relax DataRow rubric to account for MSTest 3.8.0 fixing the
  16-parameter constructor limit

writing-mstest-tests eval.vally.yaml:
- Make 3 prompts more open-ended by removing API name hints
  (Assert.HasCount, Assert.StartsWith, DynamicData to ValueTuples)
  so baseline model cannot answer confidently without the skill
2026-05-13 17:49:55 +02:00
YuliiaKovalova f1b09eba79 dotnet-test: add unit-under-test + behaviors quality cue to code-testing-generator (#646)
* CTA: invocation-only baseline (dispatch mechanics, no content rules)

Experiment branch to isolate the impact of "invoke prompted subagents
more often" from the impact of "make those subagents do richer work."
Same baseline as dev/ykovalova/cta-prompt-tuning (main = 66628b6), but
strips out every content/quality rule and keeps only the dispatch
plumbing.

Comparison branch: dev/ykovalova/cta-prompt-tuning (HEAD: bd530be)
which contains both the dispatch mechanics AND content/quality rules.

Files modified (3 vs 5 in cta-prompt-tuning):
- code-testing-generator.agent.md  +110 lines
- code-testing-implementer.agent.md +11 lines
- code-testing-fixer.agent.md      +1  line
- code-testing-researcher.agent.md  UNTOUCHED (baseline)
- code-testing-planner.agent.md     UNTOUCHED (baseline)

KEPT (invocation / dispatch mechanics):

Generator:
- Rule 1: every task() call MUST use agent_type "dotnet-test:code-testing-..."
  (without this, calls dispatch generic built-ins and never reach the
  named CTA agents)
- Rule 2: routing table -- which named agent for which job
- Rule 3: prefer one named-agent dispatch over many tool calls
- Rule 4: orchestrator MUST NOT edit/create test files itself
  (forces implementer dispatch)
- Rule 5: orchestrator MUST NOT run builds/tests via terminal
  (forces builder/tester dispatch)
- Rule 6: every run MUST dispatch the planner (no exceptions for "small"
  scope; Direct still goes through planner)
- Rule 7: every build/test failure MUST dispatch the fixer
- Step 1b: mandatory initial researcher dispatch (every strategy)
- Direct strategy rewritten: dispatches planner -> implementer -> builder
  -> tester -> fixer -> linter (was "Skip Steps 3-5, write tests inline")
- All Step 3/4/5/6/7/8/9 dispatches converted from runSubagent({agent:...})
  to task({ agent_type: "dotnet-test:code-testing-...", name:..., prompt:...})
- Step 9 validator dispatch (forces builder dispatch for cleanup)
- Steps 6/7 mandatory builder/tester dispatch wrapper

Implementer:
- Section 5: "you MUST dispatch fixer for build errors" + no-inline-edit
  block (forces fixer dispatch on build failures)
- Section 6: "you MUST dispatch fixer for test failures" + no-inline-edit
  block (forces fixer dispatch on test failures)
- Section 7: "Format Code (mandatory if a lint command exists)"
  (was "Optional"; mandatory firing of linter)
- Rule 6: never declare SUCCESS while build/tests fail (gates SUCCESS on
  fixer dispatch)
- Rule 7: no inline test-file edits between failed dispatch and fixer

Fixer:
- Frontmatter description widened to advertise handling of failing tests
  (without this, the orchestrator's routing logic does not select the
  fixer for test failures, so even Rule 7's mandate produces no firing
  -- this is the change that took fixer firing from 0.00/inst to 0.39/inst
  in earlier iterations)

DROPPED (content / quality rules -- in cta-prompt-tuning, NOT here):

Generator:
- Test-strength rules embedded in implementer dispatch prompt
- Test-design rules embedded in implementer dispatch prompt (OFAT,
  mutation self-check, never mock subject under test)
- File-location rules embedded in implementer dispatch prompt
- TARGET ENTITIES / PHASE CHECKLIST / TEST TRACEABILITY blocks in
  implementer dispatch prompt
- CHECKLIST format spec in planner dispatch prompt
- Step 9 validator's detailed cleanup classification

Implementer:
- Section 4b "Verify CHECKLIST coverage" pre-completion check
- Section 8 "CHECKLIST COVERAGE" report block
- "Honor the CHECKLIST" rule

Fixer:
- "Process -- Failing Tests" section (5-step diagnosis flow)
- All anti-weakening / anti-skipping rules
- "Re-derive expected from production source" guidance

Planner:
- CHECKLIST format ("one item per TARGET BEHAVIOR, Source/Variants/
  Expected mandatory")
- "Test name from research.md conventions" rule
- "At least 2 phases" rule

Researcher:
- Section 8 "Extract Local Test Naming & Style Conventions"
- TARGET ENTITIES / TARGET BEHAVIORS / TEST INFRASTRUCTURE structure
  in research.md
- Test naming pattern extraction

WHAT THE SUBAGENTS WILL ACTUALLY DO:

The researcher / planner / implementer / fixer all operate at baseline
behavior -- they receive the same prompts they receive in the upstream
"vanilla" runs. The only difference vs vanilla is that the orchestrator
ACTUALLY DISPATCHES THEM (where vanilla often inlines the work or skips
sub-agent dispatch entirely).

EXPECTED COMPARISON:

If quality on this branch is similar to or higher than dev/ykovalova/
cta-prompt-tuning (bd530be), then "more dispatches" is the dominant
quality lever and the content/quality rules in cta-prompt-tuning are
adding marginal or noise-level value.

If quality on this branch is materially lower than cta-prompt-tuning,
then the content/quality rules are doing the heavy lifting and the
dispatch mechanics alone are insufficient.

If quality on this branch matches or exceeds vanilla but trails
cta-prompt-tuning, then the dispatch mechanics provide a baseline lift
and the content rules add an incremental quality layer on top.

Rubber-duck check passed (validated dispatch-vs-content classification;
fixer frontmatter is routing metadata not a runtime gate; surviving
dispatch prompts contain no dangling references to removed CHECKLIST /
TARGET ENTITIES / TEST STRENGTH / naming-convention concepts).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* CTA: extract unit-under-test + behaviors quality cue (no caps)

* Address PR #646 review feedback

- Step 1b prompt: explicitly request unit-under-test (file:line) and behaviors
  so the verification gate rarely needs re-dispatch.
- Step 3: rename to 'Deep Research Phase', mark skipped for Direct strategy,
  and switch from overwriting research.md to extending it (no double-research).
- Step references: update '6-9' -> '6-10' and 'Step 9' -> 'Steps 9-10' in the
  strategy table and the All-strategies-MUST line, since reporting is Step 10.
- Step 6 builder prompt: drop '*.sln' glob (could expand to multiple args);
  use 'dotnet build --no-incremental' (auto-discovers .sln) per dotnet.md.
- Step 9: stop overloading the builder agent; perform diff/cleanup directly
  in the orchestrator (Rule 5 forbids inline build/test, not git/fs hygiene).
- Fixer agent: update mission text to cover failing tests and assertion
  correction (front-matter description already mentioned this; body now
  matches), with explicit no-Ignore/no-Skip/no-production-rewrite guardrails.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Yuliia Kovalova <ykovalova@example.com>
2026-05-13 14:03:31 +02:00
Amaury Levé 4c40b873f2 Add detect-static-dependencies evals for report structure, obj exclusion, and lambda statics (#640)
Cover previously uncovered skill aspects:
- [Validation] All .cs files in scope were scanned (check count)
- [Validation] Report includes category totals, top patterns, and affected files
- [Validation] obj/ and bin/ directories were excluded
- [Pitfall] Scanning obj/ or generated code
- [Pitfall] Missing statics inside lambdas/LINQ
- [WorkflowStep] Step 4: Present the report

Three new scenarios with supporting fixtures:
- Structured report with file count, categories, and top patterns
- Exclude obj/bin directories (with Generated.cs decoy in obj/)
- Detect statics inside lambdas and LINQ expressions
2026-05-13 11:49:18 +00:00
Jakub Jareš 6e7adc5e32 Add extension files for Python, TypeScript, and PowerShell (#617)
* Add Python and TypeScript extension files for code-testing pipeline

First-draft language extension files following the dotnet.md pattern.
These guide the polyglot test agent on build/test/lint/fix for each language.

Python: pytest-focused, environment/runner detection (Poetry/PDM/uv/Hatch),
public-API testing philosophy, common errors, mocking guidelines.

TypeScript: package-manager detection (npm/pnpm/yarn/bun), Jest+Vitest+Mocha
support, ESM/CJS guidance, TS-specific considerations, framework detection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revise python.md and typescript.md based on 10-agent review

Key changes:
- Add 'Rule #1: Investigate the repo first' as top section
- Remove generic templates (anchor to wrong conventions)
- Remove testing philosophy (unactionable for agent)
- Fix command inconsistency (parameterize with <prefix>/<exec>)
- Move dependency install to 'last resort' section
- Add error-driven fixer playbook with concrete fixes
- Fix Mocha --grep (test name, not file filter)
- Fix ESM guidance (don't change package.json type field)
- Add monorepo/workspace guidance (Nx, Turborepo)
- Add framework notes (React, Express, NestJS)
- Add Jest mock hoisting warning
- Cut from 224+289 lines to 117+136 lines (~57% reduction)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add powershell.md extension for Pester v5 test generation

Key sections:
- Repo investigation first (shell target detection)
- Pester v5 discovery vs run phase rules
- Import patterns for modules, library scripts, and executable scripts
- Cross-platform guidance (pwsh vs powershell.exe, Join-Path, casing)
- Non-terminating error handling with Should -Throw
- Mock scoping, -ModuleName, PesterBoundParameters
- TestDrive: for file-based tests
- Non-obvious assertion gotchas (Contain vs Be, Throw needs scriptblock)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Reword test infra guidance; add framework detection to dotnet.md

- Reword 'do not add' to 'use existing, only introduce if none exist'
- Add test framework detection table to dotnet.md (MSTest/xUnit/NUnit)
- Tailor wording per language (Python defaults to pytest, TS follows
  scripts.test, PS defaults to Pester)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Make Python extension framework-adaptive instead of pytest-centric

Rule #1 now searches for ALL test file formats (not just test_*.py),
explicitly calls out custom frameworks like UTscapy, and emphasizes
adopting repo conventions fully rather than layering pytest on top.

Test Commands section now has a custom framework block before the
pytest block, and Test File Naming defers to repo conventions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-13 11:16:45 +02:00
Amaury Levé 5856011d8f Add README.md for dotnet-test plugin (#636) 2026-05-11 15:54:27 +00:00
Amaury Levé d575b1faa8 Add eval scenarios for writing-mstest-tests skill coverage (#593)
* Add eval scenarios for writing-mstest-tests skill coverage

* Fix invalid YAML and remove build-validation claim from rubric

* Fix timeouts and low quality

* Improve further

* Increase timeout for string assertions scenario from 120s to 180s

Agent-Logs-Url: https://github.com/dotnet/skills/sessions/9943a60f-070b-4bea-9912-c994d1bed428

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-11 13:23:21 +00:00
Amaury Levé cfc293f8fe Fix skill activation for Assert.AreEqual overload eval scenario (#589)
The 'Fix Assert.AreEqual object overload errors after v3 upgrade' evaluation
scenario was failing because:

1. The prompt said 'latest major version' without mentioning 'v3' or 'MSTest v3',
   missing the skill's activation keywords.
2. The project file showed MSTest 3.8.0 (post-upgrade state) with no v2 context,
   while the SKILL.md 'When Not to Use' said 'Project already uses MSTest v3'.
3. The prompt's 'fix compilation issues' phrasing competed with writing-mstest-tests
   skill activation.

Changes:
- Updated prompt to explicitly mention upgrading from v2 to v3 and reference
  MSTest v3 compatibility issues
- Added XML comment in csproj showing the pre-upgrade v2 package versions
- Clarified SKILL.md 'When Not to Use' to distinguish fully-migrated projects
  from projects with active migration errors
2026-05-11 13:07:01 +00:00
Amaury Levé 9f531203ec Promote 4 experimental test skills to dotnet-test plugin (#634)
Move assertion-quality, test-gap-analysis, test-smell-detection, and
test-tagging from dotnet-experimental to dotnet-test. These skills have
demonstrated sufficient eval coverage, unique value beyond baseline model
capabilities, and are already integrated into the test-quality-auditor
agent pipeline.

Changes:
- Move skills and tests, dropping the exp- prefix
- Update all cross-references in skill descriptions and routing tables
- Update test-quality-auditor agent and eval scenarios
- Update CODEOWNERS for the moved paths
- Delete duplicate exp-dotnet-test-frameworks (identical to dotnet-test-frameworks)
- Fix stale exp-dotnet-test-frameworks reference in exp-test-maintainability

Skills held back for further iteration:
- exp-mock-usage-analysis: baseline model scores 5/5 on key scenarios
- exp-test-maintainability: quality gains offset by token overhead
2026-05-11 14:46:11 +02:00
Amaury Levé 97b23ae750 Fix timeout for Modernize legacy test patterns evaluation (#590)
The scenario was timing out on CI because:
- The 180s timeout left insufficient headroom for CI machines
  (local runs take 120-135s, CI machines are slower due to load,
  network NuGet restores, and parallel execution)

Changes:
- Add 'dotnet restore' setup command to pre-warm NuGet cache before
  the agent starts (same pattern used by migrate-mstest-v3-to-v4)
- Increase timeout from 180s to 300s to accommodate CI variability
2026-05-11 13:51:11 +02:00
Dan Moseley e7ec5a77a0 Fix markdownlint CI workflow (startup_failure since inception) (#629) 2026-05-08 08:33:08 +01:00
YuliiaKovalova 809d0b180c Improve test generation quality based on SWE Atlas benchmark analysis (#599)
* Improve test quality for benchmark performance

Based on SWE Atlas benchmark analysis (48.8% vanilla vs 19-34% CTA):

1. Default to Direct strategy for single-task requests — reduces
   multi-agent overhead that costs tokens without improving results

2. Run tests immediately in Direct strategy — catches assertion
   errors early instead of accumulating failures

3. Read source thoroughly before writing tests — trace actual logic
   and return values, not just function signatures

4. Quality over Quantity guidelines — cover stated requirements first,
   fewer focused tests beat many shallow ones

5. Verify tests are implementation-specific — tests that pass with
   an empty function body aren't testing anything useful

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Combine redundant implementation-specificity bullets into one

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-29 19:05:22 +00:00
Jan Krivanek 81946d2a38 Add proxy for CTA extension files (#583) 2026-04-24 12:19:17 +02:00
Amaury Levé 1b105d1940 Fix dotnet-test-frameworks skill activation for evaluations (#580)
* Fix dotnet-test-frameworks skill activation for evaluations

The skill had user-invocable: false and a description saying 'DO NOT USE
directly', which prevented the model from activating it during evaluation.
All 6 eval scenarios default to expect_activation: true, causing
SkillNotActivated failures on CI.

- Remove user-invocable: false from both dotnet-test and experimental copies
- Rewrite description with activation keywords matching eval prompts
  (assertion mapping, framework identification, skip annotations, exception
  assertions, lifecycle conversion, integration test markers)
- Preserve note that other analysis skills also load this as reference data

* Restore user-invocable: false, fix cross-refs, add expect_activation: false

Address review comment: remove exp-* skill references from dotnet-test-
frameworks description since those skills reference exp-dotnet-test-
frameworks instead.

Optimize eval results: this reference data skill's content is knowledge
the model already has (baseline scores 5.0/5 on most scenarios). Direct
activation adds token/time overhead without quality improvement:
- Restore user-invocable: false (correct for reference data skill)
- Shorten description to not trigger activation
- Add expect_activation: false to all 6 scenarios

The skill's value is realized when loaded by consumer skills (e.g.
test-anti-patterns), not via direct user queries.
2026-04-23 16:24:48 +02:00
Jan Krivanek 4ace5459f8 Improve agent based on C++ testing feedback (#571)
* Improve agent based on C++ testing feedback

* Rename Cpp.md to cpp.md
2026-04-23 15:52:29 +02:00
Amaury Levé f8e8191268 Add concrete pipeline examples for code-testing-agent (#572)
Add end-to-end input/output examples to anchor expected behavior for the
LLM, addressing the Example Quality (2/5) review feedback.

Changes:
- New extensions/dotnet-examples.md with .NET-specific examples: sample
  source code, research output, plan output, generated test file, fix
  cycle walkthroughs, and final report
- SKILL.md: replace one-liner examples with strategy selection table,
  pipeline walkthrough, and pointer to language-specific extensions
- Generator agent: add strategy decision examples and sample final report
- Researcher/Planner/Implementer agents: add references to extension
  examples for concrete output shapes

Architecture keeps core agents language-agnostic — all language-specific
examples live in the extensions/ folder.
2026-04-23 12:18:36 +00:00
Amaury Levé 8651264f12 Fix skill activation for exit code 8 scenario (#567)
* Initial plan

* Improve MTP migration skill guidance for OutputType conditions

Agent-Logs-Url: https://github.com/dotnet/skills/sessions/ae2f9ae1-c8c3-4e50-95ab-ccdc08bc388b

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>

* Add eval scenario for OutputType conditioning in Directory.Build.props

Agent-Logs-Url: https://github.com/dotnet/skills/sessions/734b3736-45a4-4f5d-b83c-3e6ee72fcfae

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>

* Fix skill activation for exit code 8 scenario

Add 'zero tests discovered', 'MTP behavioral differences', '--ignore-exit-code', and 'TESTINGPLATFORM_EXITCODE_IGNORE' to skill description to improve activation for the exit code 8 eval scenario. Consolidate filter syntax mention to stay within 1024-char limit.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-04-21 19:10:25 +02:00
Jan Krivanek 05aeb657e6 Add license to agent files (#568) 2026-04-21 12:57:18 +00:00
Artur Spychaj 270ef910ec Ensure validation runs for all strategies including Direct (#570)
Harden the test generator agent to ensure final build validation, test
validation, and git commit always run — even when using the Direct
strategy for small requests.

Changes:
- Step 1: Mandate reading language-specific extensions (e.g., dotnet.md)
  before writing any code. The extension contains critical project
  registration (dotnet sln add) and build validation guidance.
- Step 2: Direct strategy now skips only Steps 3-5 (research, plan,
  implement sub-agents), NOT Steps 6-9. Added explicit note that
  Steps 6-9 are mandatory for ALL strategies.
- Step 6: Clarify full-solution build must use no --framework flag to
  catch multi-target framework issues (e.g., net472 errors).
- Step 7: Require fresh build for final test validation (no --no-build).
- New Step 9: Explicit git commit with verification that the diff is
  non-empty.
- New rules 9-11: Read extensions first, always validate+commit,
  preserve existing tests.

Motivated by MSBench investigation showing:
- Agent used Direct strategy and skipped final validation entirely
- Agent never read extensions/dotnet.md (missing dotnet sln add)
- Agent forgot to git commit (300 tests created, Changes +0 -0)
- Agent deleted pre-existing tests while adding new ones

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 14:27:32 +02:00
Copilot c625f09db5 Recommend MSBuildProjectName for OutputType conditions in MTP migration skill (#556)
* Initial plan

* Improve MTP migration skill guidance for OutputType conditions

Agent-Logs-Url: https://github.com/dotnet/skills/sessions/ae2f9ae1-c8c3-4e50-95ab-ccdc08bc388b

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>

* Add eval scenario for OutputType conditioning in Directory.Build.props

Agent-Logs-Url: https://github.com/dotnet/skills/sessions/734b3736-45a4-4f5d-b83c-3e6ee72fcfae

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 07:24:59 +00:00
Amaury Levé 5826c421b4 Fix test-anti-patterns plugin activation by disambiguating competing descriptions (#552)
The test-anti-patterns skill was not reliably activated in plugin mode
because sibling descriptions overlapped:

- test-quality-auditor agent: narrowed to multi-skill audit pipelines
  only, explicitly excluding single-file reviews
- writing-mstest-tests skill: removed 'review' and 'anti-patterns' from
  description, added explicit exclusion for test quality auditing
- test-anti-patterns skill: expanded trigger phrases to better match
  review prompts (flaky tests, duplication, tests that pass without
  verifying)
2026-04-21 09:13:20 +02:00
Amaury Levé 7841934a75 Add migrate-mstest-v3-to-v4 eval scenarios for uncovered patterns (#564)
* Add migrate-mstest-v3-to-v4 eval scenarios for uncovered patterns

Add 5 new scenarios (Goals 10-14) covering:
- Verified package update with build/test validation
- Sealed custom TestMethodAttribute with Timeout migration
- TestMethodAttribute/TestMethod display name constructor syntax
- Assert.IsInstanceOfType out parameter breaking change
- TreatDiscoveryWarningsAsErrors and behavioral changes review

Add 4 new fixture directories:
- v3-verified-migration: buildable project for end-to-end validation
- v3-sealed-timeout: sealed attr + TestTimeout.Infinite patterns
- v3-testmethod-displayname: [TestMethod/Attribute("name")] patterns
- v3-instanceoftype: Assert.IsInstanceOfType<T> out param pattern

Covers uncovered validation items (lines 449-451, 458) and code
patterns: [TestMethod], [Timeout], sealed, [TestMethodAttribute],
Assert.IsInstanceOfType.

* Improve skill description for activation and bump scenario timeouts

Rewrite migrate-mstest-v3-to-v4 frontmatter description to improve SDK
semantic matching:
- Lead with symptom (fix build errors) instead of action (migrate)
- Add error codes CS0507, CS0103, CS1061, CS1615 as trigger signals
- Add symptom phrase: tests don't compile after upgrading MSTest
- Expand breaking change keywords: sealed, DisplayName syntax,
  Assert.IsInstanceOfType out parameter, TestContext.TestName
- Keep under 1024 char limit

Bump timeout 180s -> 240s for scenarios 11 (sealed attr) and 13
(IsInstanceOfType) that hit timeout during evaluation.

* Address PR review comments

- Remove unused 'using System' from OrderServiceTests.cs and TypeCheckTests.cs
- Renumber duplicate Goal 10 to Goal 15 (non-activation scenario)
- Tighten file_contains assertion to check MSTest.TestFramework and
  MSTest.TestAdapter individually instead of broad '4.' match
- Tighten Timeout assertion to require int.MaxValue instead of matching
  pre-migration symbol names
- Fix error code CS0507 -> CS0115 in scenario 11 prompt to match the
  actual MSTest v4 error for missing Execute override
2026-04-21 09:12:45 +02:00
Amaury Levé 1125fe7864 improve(dotnet-test): enhance agent descriptions for subagent discovery (#560)
- Add 'Use when:' trigger phrases to all 7 sub-agent descriptions
  so parent agents can reliably discover and delegate to them
- Add .testagent/ cleanup rule to generator agent to prevent
  ephemeral pipeline state from being committed
2026-04-20 19:51:09 +02:00
Amaury Levé 9ab90d6400 feat(dotnet-test): add handoffs between orchestrator agents (#561)
- test-quality-auditor -> code-testing-generator (generate missing tests)
- test-quality-auditor -> testability-migration (fix untestable code)
- testability-migration -> code-testing-generator (test migrated code)
- test-migration -> test-quality-auditor (audit after migration)

Enables guided sequential workflows between agents with suggested
next steps, per VS Code custom agent handoff pattern.
2026-04-20 19:36:44 +02:00
Copilot a4927f1b79 Align writing-mstest-tests skill routing with anti-pattern disambiguation (#553)
* Initial plan

* fix(dotnet-test): align writing-mstest-tests routing with anti-pattern skill

Agent-Logs-Url: https://github.com/dotnet/skills/sessions/eb70209e-8e7a-4b49-820d-65e0e3fcaedc

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
2026-04-20 14:59:26 +02:00
Amaury Levé 400661df09 run-tests: add critical rules, detection guidance, and troubleshooting (#514)
* run-tests: add critical rules, detection guidance, and troubleshooting

- Add 'Critical Rules' table to prevent cross-platform VSTest/MTP mistakes
- Expand Step 1 detection with explicit file-by-file lookup table
- Add 'dotnet --version' as first detection action
- Add Troubleshooting section with 7 common error patterns
- Expand Common Pitfalls from 3 to 7 entries
- Strengthen negative guidance for SDK version-specific syntax

* Improve description

* Improve evaluation

* Add expected and rejected tools

* Change

* Improve do not use sections

* Improve prompt

* Increase eval timeouts for scenarios hitting the limit

- run-tests: trx reporting MTP SDK 9 (360s -> 480s)
- run-tests: blame-hang MTP SDK 10 (300s -> 420s)
- run-tests: combine filter criteria VSTest (180s -> 300s)
- mtp-hot-reload: hot reload SDK 9 (360s -> 480s)
- mtp-hot-reload: hot reload filter (180s -> 300s)
- code-testing-agent: ContosoUniversity (1800s -> 2400s)
2026-04-20 10:09:15 +02:00
Amaury Levé 7791735b60 Add test-quality-auditor hub agent for .NET test suite analysis (#541)
* Add test-quality-auditor hub agent for .NET test suite analysis

Introduces a new test-quality-auditor agent that triages test quality
concerns to specialized analysis skills: assertion quality, test smells,
anti-patterns, mock usage, test gaps, maintainability, coverage risk,
and test tagging. Includes a comprehensive audit pipeline that chains
multiple skills for broad health checks.

* Address Copilot review: clarify diagnostic role and coverage routing

- Reword intro to acknowledge file-modifying workflows (test tagging)
  are only used with explicit user confirmation
- Clarify coverage-analysis vs crap-score: prefer coverage-analysis for
  project-wide analysis, reserve crap-score for targeted method/class scope
2026-04-17 17:54:33 +00:00
Amaury Levé f9d7faf0ee Add test-migration hub agent for .NET test framework and platform migrations (#540)
* Add test-migration hub agent for .NET test framework and platform migrations

Introduces a new test-migration agent that auto-detects the current test
framework, version, and platform, then routes to the appropriate migration
skill (MSTest v1/v2→v3, v3→v4, xUnit v2→v3, VSTest→MTP). Handles
multi-step migrations with commit boundaries between steps.

* Align framework detection with platform-detection skill

Address Copilot review: MSTest requires metapackage, Sdk, or both
TestFramework+TestAdapter (not either alone). Add missing xUnit MTP
package variants.
2026-04-17 19:53:32 +02:00
Artur Spychaj 3dbe832796 Add 'dotnet sln add' step to code-testing-implementer (#522)
* Add 'dotnet sln add' step to code-testing-implementer

When a new test project is created, register it with the solution
file using 'dotnet sln add' so that 'dotnet test <solution>'
discovers the tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review: improve dotnet sln add guidance

- Use solution identified in research/plan rather than searching
- Account for .slnf solution filter scenarios
- Prefer 'dotnet test --solution' over 'dotnet test <solution>'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move dotnet sln add guidance to dotnet.md extension

The implementer is polyglot, so 'dotnet sln add' doesn't belong
there. Replace with a generic 'register with build system' step
that defers to extensions/, and add the .NET-specific detail
(sln/slnx/slnf handling) to extensions/dotnet.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review: fix solution registration guidance in dotnet.md

- Include .slnf in 'don't substitute' warning alongside .sln/.slnx
- Qualify '--solution' flag as SDK 10+/MTP-only; fall back to
  positional form for older SDKs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 14:38:03 +02:00
Amaury Levé 7e6954f9a9 Add testability migration skills and agent for dotnet-test (#518)
* Add testability migration skills and agent for dotnet-test

Introduces three skills and one orchestrator agent to help developers
incrementally replace hard-to-test static dependencies with injectable
abstractions:

- detect-static-dependencies: scans C# code for DateTime.Now, File.*,
  Environment.*, HttpClient, Console.*, Process.* and ranks by frequency
- generate-testability-wrappers: generates wrapper interfaces or guides
  adoption of built-in abstractions (TimeProvider, IHttpClientFactory,
  System.IO.Abstractions)
- migrate-static-to-wrapper: mechanical codemod-style bulk replacement of
  static call sites with wrapper calls, scoped per project/namespace
- testability-migration agent: orchestrates the Detect-Generate-Migrate
  pipeline end-to-end

Includes eval.yaml tests and fixture projects for all three skills and
the agent.

* Fix activation, token overhead, and eval timeouts

- Expand skill descriptions with more trigger phrases for
  migrate-static-to-wrapper and generate-testability-wrappers
  to fix NOT ACTIVATED issues
- Collapse verbose replacement mapping tables and constructor
  examples to reduce token overhead (~30% fewer tokens)
- Increase generate-testability-wrappers eval timeouts from
  120s to 240s to prevent timeout-impacted scoring
- Soften detect-static-dependencies scenario 2 rubric to
  reduce run-to-run variance in plugin mode
- Increase migrate-static-to-wrapper non-activation timeout
2026-04-13 15:59:41 +02:00
Copilot 7ab8006c18 Fix markdownlint violations in dotnet-test plugin (#513)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
2026-04-10 15:52:21 +00:00