Official agent skill

Test Smell Detection

by dotnet in dotnet/skills

Audits existing tests in any language using formal, research-backed test smell names and the testsmells.org 19-smell academic taxonomy.

OfficialMITAuto-check passedMobile

Install Test Smell Detection

skills CLI
$ npx skills add dotnet/skills --skill test-smell-detection -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install dotnet/skills test-smell-detection --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/dotnet/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/dotnet-test/skills/test-smell-detection .claude/skills/test-smell-detection && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
test-smell-detection
GitHub stars
5.6k
Used in
1 other repo
Token cost
~2.5k tokens
SKILL.md length
1,283 words
Files
2 (incl. references)
Skills in repo
91
Repo updated
First seen
Licence
MIT

At a glance

Audits existing tests in any language using formal, research-backed test smell names and the testsmells.org 19-smell academic taxonomy.

  • Works in 5 steps: Search for and read the staged tests;… → Read the tests and only verdict-changing… → For each candidate, verify the executed… → …
  • The caller asks for an academic
  • SKILL.md covers Scope, Audit Workflow, High-Signal Decisions and Calibration Rules, plus 3 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Test Smell Detection is an agent skill from dotnet/skills, published by the product's own GitHub organization. Audits existing tests in any language using formal, research-backed test smell names and the testsmells.org 19-smell academic taxonomy. Use when the caller asks for an academic or citable test-smell review, named smell categories, or a formal severity-ranked smell assessment. Covers Assertion Roulette, Conditional Test Logic, Mystery Guest, Eager Test, Sleepy Test, Unknown Test, Sensitive Equality, and the rest of the catalog across .NET, Python, JavaScript/TypeScript, Java, Go, Ruby, Rust, Swift, Kotlin…

Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/test-smell-catalog.md`).

It sits in Mobile, covering Code migrations, Android development and iOS development. It works with .NET, C++, Java and JavaScript. The repository describes itself as: Repository for skills to assist AI coding agents with .NET and C. The licence is MIT.

When your agent uses it

  • The caller asks for an academic
  • Citable test-smell review
  • Named smell categories
  • A formal severity-ranked smell assessment

Example prompts

  • “Use the test-smell-detection skill to audit existing tests in any language using formal, research-backed test smell names and the testsmells.org…”
  • “/test-smell-detection”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Search for and read the staged tests; detect language, framework, boundaries,
  2. Read the tests and only verdict-changing production context.
  3. For each candidate, verify the executed check, choose the formal category,
  4. Rank confirmed findings by risk of false confidence or flakiness, then by
  5. Give a framework-correct replacement for each actionable finding. Never use

What it can do on your machine

Read from SKILL.md and the folder at commit a660de8. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Test Smell Detection loads about 2.5k tokens when it runs, and up to ~4.1k if it reads all its reference files. Until then it costs about 178 tokens; SKILL.md has 1,283 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~178
When it runs · the whole SKILL.md, loaded when a task matches
~2.5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from dotnet/skills at commit a660de8, republished under its MIT licence (© dotnet). 1,283 words, ~2,476 tokens.

Download SKILL.mdSave it as .claude/skills/test-smell-detection/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
test-smell-detection
description
Audits existing tests in any language using formal, research-backed test smell names and the testsmells.org 19-smell academic taxonomy. Use when the caller asks for an academic or citable test-smell review, named smell categories, or a formal severity-ranked smell assessment. Covers Assertion Roulette, Conditional Test Logic, Mystery Guest, Eager Test, Sleepy Test, Unknown Test, Sensitive Equality, and the rest of the catalog across .NET, Python, JavaScript/TypeScript, Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, and C++. DO NOT USE FOR a quick pragmatic test review (use test-anti-patterns), writing or running tests, framework migration, coverage, or assertion-diversity metrics.
license
MIT

Test Smell Detection

Audit test code with the academic taxonomy, code evidence, calibrated framework idioms, and fixes native to the codebase.

Scope

  • Audit only staged or named tests. Search the current workspace before asking for code; never claim a file is missing until that search finds no relevant test.
  • Read production code only when it changes a verdict.
  • For unfamiliar framework APIs, call test-analysis-extensions and read the matching language extension.
  • Read the complete catalog when the caller requests all 19 smells, asks for citations, or the code may contain a smell outside the high-signal set below. Do not load it for a narrow question that this file answers.

Audit Workflow

  1. Search for and read the staged tests; detect language, framework, boundaries, and integration markers. This is the first action even when no path is named.
  2. Read the tests and only verdict-changing production context.
  3. For each candidate, verify the executed check, choose the formal category, calibrate, then assign severity. Report proven non-catalog test-validity defects separately; do not relabel them as smells.
  4. Rank confirmed findings by risk of false confidence or flakiness, then by maintenance cost.
  5. Give a framework-correct replacement for each actionable finding. Never use .NET terminology or APIs in another ecosystem.

High-Signal Decisions

EvidenceAcademic findingDoNever
Assertion behavior changes behind if, switch, or branching loopsConditional Test LogicSplit cases or parameterize themFlag table-driven or parametrized tests merely because a runner loop exists
A test relies on an undeclared file, network service, environment value, or databaseMystery Guest or Resource OptimismMake the dependency explicit and hermetic; distinguish the two using the full catalogCondemn an integration test merely for exercising its declared real resource
Fixed wall-clock sleep waits for an outcomeSleepy TestAwait or poll the condition with a timeoutDowngrade it only because the test is an integration test
Executable test has no assertion, expected-exception marker, or mock verificationUnknown TestAssert the observable outcomeCall an empty body Unknown Test; the formal name is Empty Test
Async assertion/coroutine is created but not awaited or returnedCritical non-catalog false-pass defectReport it separately and show the required await/returnForce it into Unknown Test; the assertion statement exists
One test exercises many unrelated production behaviorsEager TestSeparate behavior-focused testsFlag a deliberate end-to-end workflow without considering its scope
Expected numeric literal has no local meaningMagic Number TestName the domain value or derive it from setupFlag count == 3 immediately after adding three items
Assertion depends on ToString, repr, description, or display formatting that is not the contractSensitive EqualityAssert stable fields or use a structural matcherFlag a test whose explicit contract is the formatted string
Test manually manages expected exception flowException HandlingUse the framework's exception assertion and check meaningful detailsClaim a capture-and-assert test verifies nothing
Shared setup creates state irrelevant to the tests that receive itGeneral FixtureRemove unused state or narrow the fixture; rank cheap state lowCondemn relevant shared setup merely because it is shared
Test is disabled or skippedIgnored TestReport every skip, but rank a tracked, reasoned skip below an unexplained oneClear a skip because its reason is good, or give both the same urgency

Calibration Rules

Apply these before assigning a finding:

  • Mock-call verifications, snapshots, bare pytest assert, Pester Should -Invoke, and expected-exception constructs are assertions.
  • A literal or snapshot assertion may expose a coverage gap, but is not Unknown Test or another smell without separate evidence.
  • Count assertion statements. One assertion is never Assertion Roulette; missing messages alone are not a smell.
  • Same-method tests are not Lazy Test when they cover distinct behaviors, boundaries, or state; require redundant equivalent paths.
  • General Fixture requires shared lifecycle state. Repeated local construction is neither General Fixture nor Test Code Duplication by itself.
  • Treat strings returned by the public API as observable contract unless production context or requirements make them display-only; interpolation alone is not Sensitive Equality.
  • Magic Number Test requires an unexplained oracle value. Do not flag ordinary setup quantities whose role is locally obvious and irrelevant to the asserted behavior.
  • Go table-driven subtests, pytest/JUnit/xUnit parameterization, Jest/Vitest .each, RSpec data tables, Pester -ForEach, and Catch2 SECTION/GENERATE are not Conditional Test Logic by themselves.
  • Go's if err != nil { t.Fatal(...) } is idiomatic assertion flow, not Exception Handling.
  • Integration markers legitimize declared external resources and multi-step flows, but not fixed sleeps or assertion-free execution.
  • For integration tests, trace helper factories and repository return types before judging branch coverage. If a test branches on a subtype or state that the real helper can never produce, report the unreachable assertion path and explain the resulting false confidence. Do not stop at assigning the generic Conditional Test Logic label.
  • A local temporary file still meets the formal Mystery Guest definition. Hermetic creation and cleanup reduce its severity; they do not change its taxonomy.
  • A formatting name does not prove display text is the stable contract; confirm it from production behavior or requirements before clearing Sensitive Equality.
  • Do not infer a smell from method names alone. Point to the statement or fixture relationship that proves it.
  • Do not infer a high-severity non-catalog validity defect from a test name alone. Without production code or an explicit contract proving that the test is supposed to invoke another component, a name/body mismatch is at most an unranked observation, not evidence that the test silently passes broken production behavior.
  • Catch2 SECTION and GENERATE are runner-controlled case expansion, and REQUIRE is a real assertion. When those are the only suspicious constructs, the academic-smell verdict is clean. Do not reverse that verdict because the test could have broader behavioral coverage.
  • If no material smell remains after calibration, say that clearly. Never manufacture findings to fill a report.
  • Never propose await for a void or otherwise non-awaitable API. If production work is synchronous, remove the sleep and assert immediately.
Show full SKILL.md (304 more words)Show less

Severity

Severity follows demonstrated risk, not a fixed label copied from the catalog:

  • High: can silently pass while behavior is broken, creates nondeterministic failures, or hides unexecuted assertion paths.
  • Medium: makes failures ambiguous or couples tests to unstable details.
  • Low: primarily maintenance debt, such as a reasoned skip or over-broad cheap fixture.

State the reason for the assigned severity. Downgrade or omit a finding when the surrounding test type makes the pattern intentional.

Output Contract

Scale the response to the input:

  • For one to three files, give a verdict and one compact table: severity, formal smell, evidence, risk, and fix.
  • For larger suites, add counts and a short priority order. Do not repeat findings across dashboards, prose, and plans.
  • Show code only when it clarifies a fix; omit unchanged setup.
  • Add brief Not findings only for plausibly suspicious idioms.
  • Put proven non-catalog validity defects after the academic-smell verdict. On a clean input with no production contract, do not assign severity to optional coverage observations or let them overturn the clean verdict.
  • Do not narrate discovery or catalog loading; return the audit directly.

Every reported smell must have a formal taxonomy name, precise location, evidence from the code, practical risk, and a concrete framework-correct fix.

Validation

  • Every finding is supported by code, not a keyword or method name.
  • Unknown Test and Empty Test remain distinct.
  • Every disabled test remains Ignored Test, and every local file dependency remains Mystery Guest; rationale and hermetic cleanup change severity only.
  • Framework idioms and integration boundaries were calibrated before reporting.
  • Clean tests and suspicious-but-valid idioms are not turned into filler.
  • Clean framework idioms are not converted into high-severity non-catalog findings from naming or absent production context.
  • Fixes use the target framework's APIs and preserve the behavior under test.
  • Claims about files reviewed, builds, or test runs match actions actually performed.

© dotnet, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (references) in plugins/dotnet-test/skills/test-smell-detection of dotnet/skills.

  • SKILL.md
  • references/test-smell-catalog.md

Open the folder on GitHubat commit a660de8

Used in 1 other repository

We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in dotnet/skills, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Test Smell Detection next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Test Smell Detection compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Test Smell Detection this skilldotnet/skills5.6k1 repos~2.5kAutomated safety check: PassMIT
Fory Version Bumpapache/fory4.6k—~1.1kAutomated safety check: PassApache-2.0
Fory Performance Optimizationapache/fory4.6k—~2.2kAutomated safety check: PassApache-2.0
Code Revieweralirezarezvani/claude-skills28k1 repos~1.6kAutomated safety check: PassMIT
Code Testing Extensionsmicrosoft/testfx1k2 repos~930Automated safety check: PassMIT
Build Teaql Appteaql/teaql-agent-kit2.8k—~4.6kAutomated safety check: PassMIT

Similar skills

  • Bump Apache Fory release or post-release development versions across Java, Kotlin, Scala, Python, Rust, Go, C++, C, Dart, JavaScript, Swift, integration tests, examples, and source docs.

    4.6k GitHub stars~1.1k tokensUpdated yesterday
    MobileAuto-check passed
  • Run profile-driven bottleneck optimization across Apache Fory implementations (Java, C++, Python/Cython, Go, Rust, Swift, C, JavaScript/TypeScript, Dart, Kotlin, Scala).

    4.6k GitHub stars~2.2k tokensUpdated yesterday
    MobileAuto-check passed
  • Code Reviewer

    alirezarezvani/claude-skills

    Code review automation for TypeScript, JavaScript, Python, Go, Swift, Kotlin, C, .NET, Java, C, C++, Rust, Ruby, PHP, and Dart/Flutter.

    28k GitHub starsUsed in 1 repo~1.6k tokens
    DevelopmentAuto-check passed
  • Code Testing Extensions

    microsoft/testfx

    Official

    Provides file paths to language-specific extension files for the code-testing pipeline.

    1k GitHub starsUsed in 2 repos~930 tokens
    Testing & QAAuto-check passed
  • Build Teaql App

    teaql/teaql-agent-kit

    Build or change a TeaQL application in Java, Rust, Go, Swift, Python, C/.NET, or TypeScript, including Kotlin/JVM applications that consume Java-generated libraries.

    2.8k GitHub stars~4.6k tokensUpdated 11 days ago
    MobileAuto-check passed
  • Build Nitro Modules

    margelo/react-native-skills

    Builds and designs React Native Nitro Modules with Nitrogen, HybridObject TypeScript specs, Nitro View components, generated native implementations, zero-copy and native-state APIs, Swift/Kotlin/C++…

    175 GitHub stars~9.9k tokensUpdated 1 mo ago
    MobileAuto-check passed

More from dotnet/skills

All 91 skills in this repo
  • Official

    Resolves .NET runtime frames in Apple .ips crash logs to function names, source files and line numbers using dSYM symbols, atos and the Microsoft symbol server.

    5.6k GitHub starsUsed in 1 repo~2.4k tokens
    Auto-check passed
  • Official

    Resolves native crash frames from .NET Android tombstones to function names, source files and line numbers using BuildIds, Microsoft's symbol server and llvm-symbolizer.

    5.6k GitHub starsUsed in 1 repo~2.1k tokens
    Auto-check passed
  • Official

    Scans C# and .NET code for about 50 performance anti-patterns and reports prioritized findings with concrete fixes, at a scan depth you choose.

    5.6k GitHub starsUsed in 3 repos~3.1k tokens
    Auto-check passed
  • Official

    Statically pairs source files with test files to list code that no test references, using Roslyn for C# or tree-sitter for many languages, with no build.

    5.6k GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Microbenchmarking

    dotnet/skills

    Official

    Activate this skill when BenchmarkDotNet (BDN) is involved in the task — creating, running, configuring, or reviewing BDN benchmarks.

    5.6k GitHub starsUsed in 3 repos~3.3k tokens
    Auto-check passed
  • Official

    Makes .NET projects compatible with Native AOT and trimming by resolving IL trim and AOT analyzer warnings through annotations rather than suppressions.

    5.6k GitHub starsUsed in 2 repos~4.2k tokens
    Auto-check passed

Categories

Questions about Test Smell Detection

What does Test Smell Detection do?

Audits existing tests in any language using formal, research-backed test smell names and the testsmells.org 19-smell academic taxonomy. Test Smell Detection is an agent skill from dotnet/skills, published by the product's own GitHub organization.org 19-smell academic taxonomy.

When should I use Test Smell Detection?

Test Smell Detection fits situations like: the caller asks for an academic; citable test-smell review; named smell categories; A formal severity-ranked smell assessment.

How do I install Test Smell Detection in Claude Code?

Run `npx skills add dotnet/skills --skill test-smell-detection -a claude-code`. Or copy the skill folder (plugins/dotnet-test/skills/test-smell-detection in dotnet/skills) into .claude/skills/test-smell-detection in your project. Claude Code loads it when a task matches its description.

How do I install Test Smell Detection in Codex?

Run `npx skills add dotnet/skills --skill test-smell-detection -a codex`. Or copy the skill folder (plugins/dotnet-test/skills/test-smell-detection in dotnet/skills) into .agents/skills/test-smell-detection in your project. Codex loads it when a task matches its description.

Can I use Test Smell Detection in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dotnet/skills --skill test-smell-detection -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/test-smell-detection, .gemini/skills/test-smell-detection, .github/skills/test-smell-detection and .opencode/skills/test-smell-detection in your project.

What does Test Smell Detection need to run?

SKILL.md names no scripts, command-line tools or credentials: Test Smell Detection is instructions for the agent only.

Does Test Smell Detection access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Test Smell Detection safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Test Smell Detection use?

Test Smell Detection is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Test Smell Detection use?

About 2.5k tokens (SKILL.md is roughly 9.9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.6k tokens, read only when the agent opens those files.

What are the alternatives to Test Smell Detection?

Skills that share tags, products or a category with Test Smell Detection: Fory Version Bump (apache/fory, 4.6k stars), Fory Performance Optimization (apache/fory, 4.6k stars), Code Reviewer (alirezarezvani/claude-skills, 28k stars) and Code Testing Extensions (microsoft/testfx, 1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Test Smell Detection?

dotnet (a GitHub organization, an official publisher) maintains it in dotnet/skills, which has 5,576 GitHub stars. The repository holds 91 skills in this directory. The repository was last updated on October 8, 2026.

Source: dotnet/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.