Test Discovery
EmeaAppGbb/spec2cloud
Catalog existing tests — discover test frameworks, count tests by type, parse coverage reports, and map test-to-feature relationships.
Write effective unit tests with Jest, Vitest, or pytest. An agent skill from petrkindlmann/qa-skills.
$ npx skills add petrkindlmann/qa-skills --skill unit-testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install petrkindlmann/qa-skills unit-testing --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/petrkindlmann/qa-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/unit-testing .claude/skills/unit-testing && rm -rf skills-srcUse ~/.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/
Install the "unit-testing" agent skill from https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testing into .claude/skills/unit-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unit-testing", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add petrkindlmann/qa-skills --skill unit-testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install petrkindlmann/qa-skills unit-testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/petrkindlmann/qa-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/unit-testing .agents/skills/unit-testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "unit-testing" agent skill from https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testing into .agents/skills/unit-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unit-testing", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add petrkindlmann/qa-skills --skill unit-testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install petrkindlmann/qa-skills unit-testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/petrkindlmann/qa-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/unit-testing .cursor/skills/unit-testing && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "unit-testing" agent skill from https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testing into .cursor/skills/unit-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unit-testing", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/petrkindlmann/qa-skills.git --path skills/unit-testing--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add petrkindlmann/qa-skills --skill unit-testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install petrkindlmann/qa-skills unit-testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/petrkindlmann/qa-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/unit-testing .gemini/skills/unit-testing && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "unit-testing" agent skill from https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testing into .gemini/skills/unit-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unit-testing", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install petrkindlmann/qa-skills unit-testingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add petrkindlmann/qa-skills --skill unit-testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/petrkindlmann/qa-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/unit-testing .github/skills/unit-testing && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "unit-testing" agent skill from https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testing into .github/skills/unit-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unit-testing", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add petrkindlmann/qa-skills --skill unit-testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install petrkindlmann/qa-skills unit-testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/petrkindlmann/qa-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/unit-testing .opencode/skills/unit-testing && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "unit-testing" agent skill from https://github.com/petrkindlmann/qa-skills/tree/main/skills/unit-testing into .opencode/skills/unit-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unit-testing", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
unit-testingWrite effective unit tests with Jest, Vitest, or pytest. An agent skill from petrkindlmann/qa-skills.
Unit Testing is an agent skill from petrkindlmann/qa-skills. Write effective unit tests with Jest, Vitest, or pytest. Covers the test-doubles taxonomy (stub/spy/mock/fake), Arrange-Act-Assert, coverage threshold configuration and CI gating, snapshot testing, fake timers, and mutation testing with Stryker/mutmut. Use when: "unit test," "Jest," "Vitest," "pytest," "mock," "coverage threshold," "test doubles," "mutation testing," "fake timers," "snapshot test." Not for: interpreting coverage reports or finding coverage gaps — use coverage-analysis; AI generating the test code…
Its SKILL.md is about 3.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/patterns.md`).
It sits in Testing & QA, covering Unit testing and Test coverage. It works with Jest, Vitest, pytest and Cypress. The repository describes itself as: 50 QA and test-automation skills for Claude Code, Codex, Cursor, and any Agent Skills Standard runtime. The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit b3bb61b. It shows what the files ask for, not the result of running them.
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.
Shell commands in SKILL.md call:
npxvitestpytestgitnpmpipbundenoFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npx, git, npm and pip, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Unit Testing loads about 3.9k tokens when it runs, and up to ~6k if it reads all its reference files. Until then it costs about 198 tokens; SKILL.md has 1,613 words of instructions outside code blocks.
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.
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.
The full file from petrkindlmann/qa-skills at commit b3bb61b, republished under its MIT licence (© petrkindlmann). 1,613 words, ~3,901 tokens.
.claude/skills/unit-testing/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.<objective>
Write unit tests that fail when the code is wrong and pass when it is right — nothing
weaker. A test that mocks every collaborator stays green while the integration is
broken; the doubles taxonomy below stops that. A `coverageThreshold` typo (or the
plural `coverageThresholds`, which Jest silently ignores) lets 40%-covered code ship
on a green pipeline; the config and Verification sections below make the gate actually
fire. This skill covers Jest, Vitest, and pytest: doubles, coverage gating, snapshots,
fake timers, and mutation testing as a behavior check on top of coverage.
</objective>
Check .agents/qa-project-context.md first — if it exists, use it and skip anything answered there.
package.json or pyproject.toml. The runner decides config keys and mock APIs.jest.config.*, vitest.config.*, .nycrc, [tool.coverage]. Determines whether you add the gate or just tune it.__mocks__/ dirs or DI containers — this sets which doubles you reach for.*.test.ts next to source) or a __tests__/tests/ tree? Match what exists; don't introduce a third location.1. Test behavior, not implementation. Verify what code does, not how. Refactoring internals should not break tests.
// Bad — implementation detail // Good — observable behavior
expect(svc._cache.size).toBe(3); expect(svc.getUser("abc")).toEqual({ id: "abc", name: "Alice" });2. Fast, isolated, deterministic. No network/disk/DB. No shared mutable state. No uncontrolled Date.now() or Math.random() — freeze them with fake timers and seeded values.
3. Arrange-Act-Assert. One clear shape per test.
it("should apply discount for orders over $100", () => {
// Arrange
const order = createOrder({ subtotal: 150 });
const svc = new DiscountService(0.1);
// Act
const result = svc.apply(order);
// Assert
expect(result.total).toBe(135);
});4. One assertion concept per test. Multiple expect calls are fine when they verify the same concept.
5. Descriptive names. "should [behavior] when [condition]", not "test calculateTotal".
The full setup/teardown, mocking, spying, timer, in-source, and monorepo examples for
each runner live in references/patterns.md. Below is what is current and what to
reach for; copy the code from the reference.
Current is Jest 30.x (30.4.2, May 2026). Jest 30 added --collect-tests,
jest.config.mts support, Temporal-aware fake timers, and clearMocksOnScope. If the
code under test uses the Temporal API or time-zone logic, Jest 30's Temporal-aware fake
timers remove a class of brittle setup.
Reach for: jest.mock() for module boundaries (jest.requireActual for partial mocks),
jest.spyOn() to wrap a real method, jest.Mocked<T> for typed mocks, and
jest.useFakeTimers() for time. See references/patterns.md § Jest.
Same API as Jest, Vite-native. Stable: Vitest 4.1.x (June 2026); 5.0.0-beta is
out (beta.3, May 2026). Vitest 4 added coverage.changed (changed-files-only coverage),
mockThrow/mockThrowOnce, and a stable browser mode. Vitest 5 beta removes the
sequential option and requires Node 22 / Vite 6.4 — wait for stable before
adopting. Mock with vi.mock/vi.spyOn; the standout features are in-source testing
(import.meta.vitest) and browser mode for component rendering. See
references/patterns.md § Vitest.
Use fixtures + conftest.py (with yield for teardown), @pytest.mark.parametrize
for data-driven cases, and monkeypatch for env/attr substitution. Prefer fixtures
over setUp/tearDown methods — fixtures compose and isolate per test. See
references/patterns.md § pytest.
bun test (Jest-compatible, no extra config) and deno test (native TS, permission
flags) are reasonable defaults when your runtime is already Bun or Deno. Prefer
Vitest/Jest for Node projects with deeper plugin ecosystems.
Pick the simplest double that does the job. Most of the time that is a stub.
| Double | What it does | When to use |
|---|---|---|
| Stub | Returns canned data, no verification | Control a dependency's return value |
| Spy | Wraps real impl, records calls | Verify calls without changing behavior |
| Mock | Replaces impl + records calls | Control return AND verify interaction |
| Fake | Simplified working impl (in-memory DB) | Complex stateful dependencies |
Rule of thumb: prefer stubs over mocks; reserve fakes for stateful dependencies;
never call a real external API in a unit test. Only mock the external boundary
(network, filesystem, DB, time) — let fast, deterministic internal collaborators run
for real, or you get a suite that is green while the integration is broken. The four
doubles in code: references/patterns.md § Test doubles.
Jest — the threshold key is coverageThreshold (singular). The plural
coverageThresholds is not a Jest key: Jest ignores it silently, the gate never
enforces, and CI stays green at 30% coverage. This is the single most common config bug.
// jest.config.js
module.exports = {
coverageProvider: "v8",
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.{d,test,stories}.ts", "!src/**/index.ts"],
coverageThreshold: { global: { branches: 80, functions: 80, lines: 80, statements: 80 } },
};Vitest — set test.coverage.thresholds in vitest.config.ts with provider: "v8"
(see references/patterns.md § Vitest for the full block).
pytest:
# pyproject.toml
[tool.coverage.run]
source = ["src"]
omit = ["src/**/test_*.py", "src/**/conftest.py"]
[tool.coverage.report]
fail_under = 80
show_missing = true
exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"]| Type | Measures | Blind spots |
|---|---|---|
| Branch | Every if/else path taken? | Misses value combinations |
| Line | Each line executed? | Misses untested branches in one line |
| Statement | Each statement executed? | Similar to line |
| Function | Each function called? | Nothing about correctness |
Priority: Branch > Line > Statement > Function. Use 80% line as the baseline gate, not a vanity target, and weight branch coverage higher. Focus coverage on business logic, transformations, error paths, and edge cases; skip generated code, type definitions, barrel exports, trivial getters, and framework boilerplate.
For interpreting which uncovered lines matter and doing gap analysis, that's
coverage-analysis, not this skill.
Jest and Vitest exit non-zero when thresholds fail — that exit code IS the gate. pytest needs the flag explicitly:
- run: pytest --cov=src --cov-fail-under=80Coverage tells you what code ran. Mutation testing tells you whether the tests would
catch a bug. It makes small source changes (> → >=, true → false) and reruns
the suite against each mutant. If the suite still passes, the mutant survived — your
tests executed that logic but did not assert on it.
npm i -D @stryker-mutator/core @stryker-mutator/jest-runner # or vitest-runner// stryker.config.json (Stryker's documented default; .mjs/.mts also load)
{
"testRunner": "jest",
"coverageAnalysis": "perTest",
"mutate": ["src/**/*.ts", "!src/**/*.test.ts"],
"thresholds": { "high": 80, "low": 60, "break": 50 },
"reporters": ["html", "clear-text", "progress"]
}Stryker's own defaults are { high: 80, low: 60, break: null } — break: null means
no failing exit. Set break (e.g. 50) to make a low score fail CI. Run: npx stryker run.
mutmut 3 dropped the old CLI surface. Configure paths in a [mutmut] block, run, then
review survivors in the TUI:
# setup.cfg (or a [tool.mutmut] table in pyproject.toml)
[mutmut]
paths_to_mutate=src/pip install mutmut # 3.5.x
mutmut run # paths come from config, not a flag
mutmut browse # interactive TUI: inspect and retest survivors
mutmut apply <mutant_id> # write a survivor to disk to see what it changedAvoid:
mutmut run --paths-to-mutate=src/,mutmut results, andmutmut show 42— that was the mutmut <3 surface. The--paths-to-mutateflag is gone (paths move to the[mutmut]config block) andresults/showare replaced bybrowse/apply(mutmut 3.5.x, verified June 2026). Following the old commands errors out on a current install.
| Score | Meaning |
|---|---|
| 90%+ | Strong — catching most logic changes |
| 70–89% | Decent — review survivors in critical paths |
| <70% | Tests execute code but do not verify behavior |
Run mutation testing on critical business logic, not the whole codebase (it is slow). Ignore equivalent mutants — logically identical code where no test could ever tell the difference.
Use for: UI component render output, serialized data structures, CLI formatting — output where exact structure matters and is tedious to assert field-by-field.
Do not use for: frequently changing output (snapshot fatigue → rubber-stamp reviews), large snapshots (unreviewable), implementation details (CSS classes, internal IDs), or as a substitute for a targeted assertion when one specific value is what matters.
Prefer inline snapshots for small output (<20 lines) and property matchers
(expect.any(String)) for dynamic fields like ids and timestamps. Always run CI with
--ci so an unknown snapshot fails instead of being silently written and committed.
Code: references/patterns.md § Snapshot testing.
Testing private methods — Test through the public API. If a private method really needs its own tests, extract it to its own module with a public surface.
Mocking everything — Only mock external boundaries (network, filesystem, DB, time). A suite where every collaborator is mocked passes while the wiring between them is broken.
The plural coverageThresholds — Jest ignores it; the gate never fires; CI is green
at any coverage. The key is coverageThreshold (singular). See Coverage above.
Faking all timers blindly — jest.useFakeTimers() / vi.useFakeTimers() with no
allowlist can deadlock code awaiting a real microtask. Fake only what the test needs
(doNotFake / toFake). See references/patterns.md § Jest timers.
Async test without await — a forgotten await makes the assertion never run and
the test passes vacuously. Add expect.assertions(n) / expect.hasAssertions() to async
tests so a missing assertion fails them.
Snapshot overuse — Use expect(x).toBe("active") for a specific value; reserve
snapshots for structured output you can't assert field-by-field.
Non-descriptive names — Replace "works" with "should return empty array when no items match the filter".
Shared mutable state — Initialize in beforeEach, not at module scope:
// Bad: shared mutation // Good: fresh per test
const items = []; let items: string[];
it("A", () => items.push("a")); beforeEach(() => { items = []; });
it("B", () => { it("A", () => { items.push("a"); expect(items).toHaveLength(1); });
items.push("b"); it("B", () => { items.push("b"); expect(items).toHaveLength(1); });
expect(items).toHaveLength(1); // FAILS
});Prove the suite runs and the gate actually fails on under-coverage — the exact thing the
coverageThreshold typo silently disables.
npx jest (or vitest run, pytest -q) exits 0.npx jest --coverage --ci # Jest/Vitest exit !=0 below coverageThreshold
vitest run --coverage # same for Vitest
pytest --cov=src --cov-fail-under=80 # pytest exits !=0 below the floor0, your threshold key is wrong (likely the plural coverageThresholds).--ci, so an unknown snapshot fails rather
than being written. git status shows no new *.snap after a CI-mode run.jest.config.* (key coverageThreshold, singular), vitest.config.* (coverage.thresholds), or pyproject.toml (fail_under) AND verified to exit non-zero below threshold (Verification step 2)__tests__/tests/) — git ls-files shows no ad-hoc test pathsgrep finds no real network/DB clients constructed in test files--ci (Jest/Vitest) so an unknown snapshot fails the build instead of being auto-writtenreferences/)© petrkindlmann, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (references) in skills/unit-testing of petrkindlmann/qa-skills.
Open the folder on GitHubat commit b3bb61b
Unit Testing 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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Unit Testing this skillpetrkindlmann/qa-skills | 163 | — | ~3.9k | Automated safety check: Pass | MIT | |
| Test DiscoveryEmeaAppGbb/spec2cloud | 100 | — | ~3.1k | Automated safety check: Pass | MIT | |
| TDD Guidealirezarezvani/claude-skills | 28k | — | ~3.4k | Automated safety check: Pass | MIT | |
| TDD GuideLeoYeAI/openclaw-master-skills | 2.2k | — | ~1.4k | Automated safety check: Pass | MIT | |
| Test Detectdavila7/claude-code-templates | 32k | — | ~989 | Automated safety check: Pass | MIT | |
| Test GuardamElnagdy/guard-skills | 1.3k | 2 repos | ~2.1k | Automated safety check: Pass | MIT |
EmeaAppGbb/spec2cloud
Catalog existing tests — discover test frameworks, count tests by type, parse coverage reports, and map test-to-feature relationships.
alirezarezvani/claude-skills
Test-driven development skill for writing unit tests, generating test fixtures and mocks, analyzing coverage gaps, and guiding red-green-refactor workflows across Jest, Pytest, JUnit, Vitest, and…
LeoYeAI/openclaw-master-skills
Test-driven development skill for writing unit tests, generating test fixtures and mocks, analyzing coverage gaps, and guiding red-green-refactor workflows across Jest, Pytest, JUnit, Vitest, and…
davila7/claude-code-templates
Auto-detect testing framework and run relevant tests. An agent skill from davila7/claude-code-templates.
amElnagdy/guard-skills
Reviews newly written or edited tests against nine rules that cut test bloat, such as mock-heavy checks and near-duplicate cases, before they are committed.
CloudAI-X/claude-workflow-v2
Designs and implements testing strategies for any codebase. An agent skill from CloudAI-X/claude-workflow-v2.
petrkindlmann/qa-skills
Test for WCAG 2.2 AA compliance with axe-core + Playwright, keyboard navigation audits, screen reader testing, ARIA pattern validation, and legal compliance mapping (ADA, EAA, Section 508).
petrkindlmann/qa-skills
Goal-driven E2E testing where a browser agent (Playwright MCP / computer-use) reads a natural-language goal and explores the app via the accessibility tree to assert outcomes — no pre-written script.
petrkindlmann/qa-skills
Use AI to write NEW test code from specs, PRDs, user stories, code diffs, bug reports, or OpenAPI specs.
petrkindlmann/qa-skills
Test REST and GraphQL APIs with Playwright APIRequestContext, Supertest, or standalone HTTP clients.
petrkindlmann/qa-skills
Design CI/CD pipelines that run test suites. An agent skill from petrkindlmann/qa-skills.
petrkindlmann/qa-skills
Test for regulatory compliance: GDPR/CMP consent verification, Google Consent Mode v2, Global Privacy Control (GPC), CCPA/US state opt-out, EU AI Act Article 50 transparency, Better Ads Standards…
Categories
Write effective unit tests with Jest, Vitest, or pytest. An agent skill from petrkindlmann/qa-skills. Unit Testing is an agent skill from petrkindlmann/qa-skills. Write effective unit tests with Jest, Vitest, or pytest.
Unit Testing fits situations like: coverage threshold; mutation testing; snapshot test. Not for: interpreting coverage reports; finding coverage gaps — use coverage-analysis.
Run `npx skills add petrkindlmann/qa-skills --skill unit-testing -a claude-code`. Or copy the skill folder (skills/unit-testing in petrkindlmann/qa-skills) into .claude/skills/unit-testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add petrkindlmann/qa-skills --skill unit-testing -a codex`. Or copy the skill folder (skills/unit-testing in petrkindlmann/qa-skills) into .agents/skills/unit-testing in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add petrkindlmann/qa-skills --skill unit-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/unit-testing, .gemini/skills/unit-testing, .github/skills/unit-testing and .opencode/skills/unit-testing in your project.
Going by SKILL.md and its folder, Unit Testing needs the command-line tools its instructions call (npx, vitest, pytest, git, npm and pip). Our summary lists: Python 3; Node.js.
SKILL.md contains no URLs. Its commands use npx, git, npm and pip, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
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.
Unit Testing is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.9k tokens (SKILL.md is roughly 16k 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 2.1k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Unit Testing: Test Discovery (EmeaAppGbb/spec2cloud, 100 stars), TDD Guide (alirezarezvani/claude-skills, 28k stars), TDD Guide (LeoYeAI/openclaw-master-skills, 2.2k stars) and Test Detect (davila7/claude-code-templates, 32k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
petrkindlmann (a GitHub user) maintains it in petrkindlmann/qa-skills, which has 163 GitHub stars. The repository holds 45 skills in this directory. The repository was last updated on June 10, 2026.
Source: petrkindlmann/qa-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.