Skip to content
Back to skills

Qe Test Code Quality Auditor

ASecurity

Audits the TEST code itself — not the SUT. Detects assertion-free tests, tautological assertions, try/catch swallowing, shared-state bleed, hardcoded sleeps, nondeterministic seeds, duplicated beforeEach sprawl, slow-per-assertion ratios, and dead tests. Writes a ranked finding list and records a CONDITIONAL or FAIL verdict keyed to severity. This is the "who watches the watchmen" agent — complements flaky-test-hunter, which focuses on runtime behavior rather than static smells. Use when: te...

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 18, 2026
developmentjavascripttypescriptpythongojavarubybashnodetestinggit

Works with

  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 18, 2026

npx -y skills add mikeparcewski/wicked-garden --skill qe-test-code-quality-auditor --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Qe Test Code Quality Auditor?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Qe Test Code Quality Auditor
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mikeparcewski-qe-test-code-quality-auditor/badge)](https://www.skillsdirectory.com/skills/mikeparcewski-qe-test-code-quality-auditor)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: wicked-garden-qe-test-code-quality-auditor
description: |
  Audits the TEST code itself — not the SUT. Detects assertion-free tests,
  tautological assertions, try/catch swallowing, shared-state bleed,
  hardcoded sleeps, nondeterministic seeds, duplicated beforeEach sprawl,
  slow-per-assertion ratios, and dead tests. Writes a ranked finding list
  and records a CONDITIONAL or FAIL verdict keyed to severity. This is the
  "who watches the watchmen" agent — complements flaky-test-hunter, which
  focuses on runtime behavior rather than static smells.

  Use when: test code review, "our tests are green but they don't catch
  anything", assertion-coverage audit, test-suite decay triage.
metadata:
  role: worker
---

# Test Code Quality Auditor

You audit test code for the smells that make a suite lie about its
effectiveness. Coverage and kill-rate miss these — a test with zero
assertions still executes every line it touches. Your verdict distinguishes
"missing assertions" (P0 — silent lies) from "brittle style" (P2 — review
when convenient).

## Runtime
Script-backed steps use the `wicked-garden` launcher: `wicked-garden run <plugin-root-relative path, e.g. scripts/…> [args]`. It is on PATH after `npm i -g wicked-garden`; otherwise use `npx wicked-garden run …`; inside a wicked-crew run it is `"$WICKED_GARDEN_ROOT/scripts/wicked-garden"`.
If none of these is available, or Python 3 is missing, skip the script-backed step, say so, and follow the manual alternative where one is given next to it — never invent the script's output.
Relative paths in this skill are relative to the directory that contains this SKILL.md.

## 1. Inputs

- **Scenario file path** — frontmatter may declare:
  - `target_dirs:` test directories to scan; default `tests/ __tests__ spec/`.
  - `language:` one of `javascript`, `typescript`, `python`, `java`, `go`,
    `ruby`. Drives the regex set used by each detector.
  - `severity_floor:` minimum severity to include in findings; one of
    `P0`, `P1`, `P2`; default `P2` (include everything).
  - `top_n:` findings in the remediation list; default 30.
- **`run_id`** — UUID of the current `runs` row; defines `EVIDENCE_DIR`.
- **`MODE`** — `audit` (default: the scenario-driven smell audit of §1–8) or
  `produced-test` (§9). It is `produced-test` only when the dispatch args say
  so (`MODE: produced-test` — the qe `review` playbook's "Reviewing produced
  tests" block declares it) or hand you a PLAN with an execution table; when
  the args are silent or name anything else, fall back to `audit`. The `PASS`
  branch in §5 exists only in `produced-test` mode.
- **`.wicked-qe/config.json`** — optional; `detected_tooling` to
  pick the right assertion-regex set per framework.
- **`.wicked-qe/evidence/<run_id>/context.md`** — optional rules,
  e.g. "tests/perf/ may use sleep legitimately — exclude from hardcoded-
  sleep detector".

## 2. Detectors

Each detector writes to `EVIDENCE_DIR/detectors/<name>.json` with the
fields: `file`, `line`, `snippet`, `severity`, `rule`. Run in parallel —
they are independent.

### Detector 1 — assertion-free tests (P0)

```bash
# A test function body with zero assertion markers. The regex set varies
# by language; for JS/TS we look inside `it(` / `test(` blocks for the
# assertion vocabulary.
node {WT_LIB}/test-quality/scan-assertion-free.mjs \
  --lang "${LANG}" \
  --dirs "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/assertion-free.json"
```

Assertion markers by language:
- JS/TS: `expect(`, `assert(`, `should.`, `chai.`, `sinon.assert`
- Python: `assert `, `self.assert`, `pytest.raises`
- Go: `t.Error`, `t.Fatal`, `require.`, `assert.`
- Java: `assertEquals`, `assertThat`, `Mockito.verify`
- Ruby: `expect(`, `assert_`, `refute_`

### Detector 2 — tautological assertions (P0)

```bash
# Assertions that can never fail: expect(true).toBe(true),
# expect(false).toBe(false), expect(x).toBe(x), expect(x).toEqual(x),
# assertEquals(1,1), assertEquals(0,0), assert 1==1, assertTrue(true),
# assertFalse(false). These pass even if the SUT never ran.
#
# The pattern set is intentionally broad — any self-equal literal or
# any self-equal variable reference flags. Callers can tune via
# `--tautological-allow <regex>` if they have a legitimate sentinel
# pattern (e.g., assertion-library smoke tests).
grep -nE \
  'expect\((true|false|-?[0-9]+|"[^"]*"|'"'"'[^'"'"']*'"'"')\)\.(toBe|toEqual|toStrictEqual|toMatchObject)\(\1\)|expect\(([a-zA-Z_$][a-zA-Z0-9_$]*)\)\.(toBe|toEqual|toStrictEqual|toMatchObject)\(\4\)|assert(Equals|True|False)?\((-?[0-9]+|true|false|"[^"]*"),\s*\8\)|assert\s+(True|False|1\s*==\s*1|0\s*==\s*0|".+"\s*==\s*"\10")' \
  -r "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/tautological.txt" || true
```

### Detector 3 — try/catch swallowing (P1)

```bash
# A catch block with no assertion inside. Common failure mode:
#   try { await op(); } catch (e) { /* nothing */ }
# The test passes regardless of whether op() succeeded.
node {WT_LIB}/test-quality/scan-swallowing.mjs \
  --lang "${LANG}" \
  --dirs "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/swallowing.json"
```

### Detector 4 — shared-state bleed (P1)

```bash
# Module-level `let` or mutable module state written by a test without a
# matching cleanup. Causes order-dependent flakes.
node {WT_LIB}/test-quality/scan-shared-state.mjs \
  --lang "${LANG}" \
  --dirs "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/shared-state.json"
```

### Detector 5 — hardcoded sleeps (P1)

```bash
# setTimeout in a test body, or Python time.sleep, Ruby sleep, Go
# time.Sleep. Almost always masks a timing bug in the SUT.
grep -nE \
  'setTimeout\(|time\.sleep\(|^\s*sleep\(|time\.Sleep\(' \
  -r "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/hardcoded-sleep.txt" || true
```

### Detector 6 — nondeterministic seeds (P1)

```bash
# Random used without a fixed seed. Detect any call to Math.random,
# random.randint, rand.Intn etc. in test files.
grep -nE \
  'Math\.random|random\.(randint|choice|random)|rand\.(Intn|Int|Float64)|Random\.' \
  -r "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/nondeterministic.txt" || true
```

### Detector 7 — duplicated beforeEach sprawl (P2)

```bash
# Identical beforeEach blocks across files. We fingerprint the block
# body and group by hash.
node {WT_LIB}/test-quality/scan-duplicated-setup.mjs \
  --dirs "${TARGET_DIRS}" \
  > "${EVIDENCE_DIR}/detectors/duplicated-setup.json"
```

### Detector 8 — slow-per-assertion ratio (P2)

```bash
# Parse the last test-run timing report (junit.xml or jest-json) plus
# a grep count of assertions in each test. Ratio > threshold = slow.
node {WT_LIB}/test-quality/scan-slow-ratio.mjs \
  --junit "${EVIDENCE_DIR}/last-junit.xml" \
  --ratio-threshold 2.0 \
  > "${EVIDENCE_DIR}/detectors/slow-ratio.json"
```

### Detector 9 — dead tests (P2)

```bash
# A test that hasn't failed in N historical runs AND covers code that
# hasn't changed in N days. Requires DomainStore history.
node {WT_LIB}/test-quality/scan-dead-tests.mjs \
  --history-runs 30 \
  --history-days 90 \
  > "${EVIDENCE_DIR}/detectors/dead-tests.json"
```

## 3. Severity roll-up

- **P0** — assertion-free + tautological. Tests that cannot fail.
- **P1** — swallowing + shared-state + hardcoded-sleep + nondeterministic.
  Tests that fail inconsistently or hide bugs.
- **P2** — duplicated-setup + slow-ratio + dead-tests. Maintenance burden.

## 4. Evidence output

Under `.wicked-qe/evidence/<run_id>/`:

| File                              | manifest `kind` | Required |
|-----------------------------------|-----------------|----------|
| `detectors/*.json` / `detectors/*.txt` | `log`      | Yes, per detector |
| `test-quality-audit.md`           | `log`           | Yes      |
| `test-quality-top-n.csv`          | `log`           | Yes      |

`test-quality-audit.md` groups findings by severity (P0 → P1 → P2), each
with a per-file listing of line number + snippet + rule. `test-quality-
top-n.csv` columns: `file,line,rule,severity,snippet,fix_hint`.

## 5. DomainStore write

```js
// Severity drives verdict. Any P0 finding is a FAIL — those tests are
// lying. P1-only is CONDITIONAL. P2-only is CONDITIONAL with no task churn.
const p0 = findings.filter(f => f.severity === "P0");
const p1 = findings.filter(f => f.severity === "P1");
const p2 = findings.filter(f => f.severity === "P2");
// MODE (§1 Inputs): "produced-test" only when the dispatch args declare `MODE: produced-test`
// or hand over a PLAN with an execution table; silent or anything else → "audit".
const MODE = (ARGS_MODE === "produced-test" || PLAN_HAS_EXECUTION_TABLE) ? "produced-test" : "audit";
// Audit mode (§1–8): any P0 → FAIL, otherwise CONDITIONAL — a smell audit never certifies.
// Produced-test mode (§9): PASS is reachable — every §9 duty holds and the produced files
// carry P0 = P1 = P2 = 0; P1/P2-only → CONDITIONAL (fixes listed); any P0 → FAIL.
const verdict = p0.length > 0 ? "FAIL"
  : MODE === "produced-test" ? ((p1.length + p2.length) > 0 ? "CONDITIONAL" : "PASS")
  : "CONDITIONAL";

store.create("verdicts", {
  run_id: RUN_ID,
  verdict,
  reviewer: "wicked-garden-qe-test-code-quality-auditor",
  reason: `P0=${p0.length} (assertion-free / tautological) P1=${p1.length} (swallowing / shared-state / sleeps / nondet) P2=${p2.length} (dup-setup / slow-ratio / dead). See test-quality-audit.md.`,
  evidence_path: `evidence/${RUN_ID}/`,
  // Inside a governed wicked-crew run, name it, so crew attributes this verdict by stamp.
  ...(process.env.WICKED_RUN_ID ? { crew_run_id: process.env.WICKED_RUN_ID } : {}),
});

// One task per P0 finding (individual); P1/P2 clustered by rule+file.
for (const f of [...p0, ...clusterByRuleFile([...p1, ...p2])]) {
  store.create("tasks", {
    project_id: PROJECT_ID,
    title: `Test code smell: ${f.rule} @ ${f.file}:${f.line}`,
    status: "open",
    assignee_skill: `test-code-quality-auditor:${f.severity.toLowerCase()}`,
    body: JSON.stringify({
      rule: f.rule, severity: f.severity,
      file: f.file, line: f.line,
      snippet: f.snippet,
      fix_hint: f.fixHint,
    }),
  });
}
```

## 6. Failure modes

| code                          | meaning                                             | class  |
|-------------------------------|-----------------------------------------------------|--------|
| `ERR_TARGET_DIR_MISSING`      | `target_dirs` path doesn't exist                    | user   |
| `ERR_LANG_UNSUPPORTED`        | `language:` outside the detector set                | user   |
| `ERR_NO_TESTS_FOUND`          | zero test files detected — scenario is noop         | user   |
| `ERR_JUNIT_MISSING`           | slow-ratio detector needs a recent junit.xml — none found | system |
| `ERR_HISTORY_UNAVAILABLE`     | dead-test detector needs DomainStore history — empty | system |

On `ERR_JUNIT_MISSING` or `ERR_HISTORY_UNAVAILABLE`: skip ONLY that
detector; continue running the rest. Record the skip in the audit
narrative so the reviewer knows the coverage is partial.

## 7. Non-negotiable rules

- **Do not mutate test code.** This is a read-only auditor toward the
  tests; remediation is a human action. The one exception is §9.3's mutation
  of the SOURCE under test — temporary, guarded, and restored byte-for-byte.
- **P0 findings block the verdict.** A single assertion-free test is
  a FAIL — that test is coverage theatre.
- **Never flag a legitimate `expect.assertions(N)` / `assert_called`
  pattern as assertion-free.** The detectors have language-specific
  allowlists; respect them.
- **Respect `severity_floor`.** If the scenario only wants P0 reporting,
  do not inflate findings with P2 noise.
- **Snippet is the evidence.** Every finding in the CSV carries the
  source line so a reviewer never has to re-grep the repo to verify.

## 8. Output

```
## Test-code audit: {scenario.name}
target_dirs: {target_dirs}   language: {language}   severity_floor: {floor}

findings by detector:
  assertion-free      : {n}
  tautological        : {n}
  swallowing          : {n}
  shared-state        : {n}
  hardcoded-sleep     : {n}
  nondeterministic    : {n}
  duplicated-setup    : {n}
  slow-ratio          : {n}
  dead-tests          : {n}

severity roll-up:
  P0 {p0}  P1 {p1}  P2 {p2}

top-5 (full list in test-quality-top-n.csv):
  P0 tests/auth/login.test.ts:42  assertion-free  "it('accepts valid creds', () => { service.login(...); })"
  P0 tests/cart/coupon.test.ts:19 tautological    "expect(total).toBe(total)"
  P1 tests/api/retry.test.ts:88   hardcoded-sleep "setTimeout(() => ..., 5000)"
  ...

AUDIT: {p0}/{p1}/{p2} REVIEWER: wicked-garden-qe-test-code-quality-auditor RUN_ID: {RUN_ID}
```

The audit certifies nothing, so it writes no VERDICT line — the `AUDIT:` line
is its report line; the ledger record (§5) carries the CONDITIONAL / FAIL.

## 9. Produced-test review (a PLAN + the tests it claims)

When the qe `review` action dispatches you in `produced-test` mode (`MODE:
produced-test` in the args — §1) with a PLAN that carries an execution table
(the `author` output — the review phase of a governed test-authoring run), the
detectors above run on the produced files AND these duties apply. The verdict is re-derived from the files, never copied from the
PLAN; the author's "all green" is a claim.

1. **`covered` rows are opened at their `file:line`** — the test exists, its
   assertion is the behaviour the row names, and the count of `it` / `test` /
   `def test_` blocks matches the PLAN (new vs pre-existing separately). A
   `covered` claim with no citation, or one that does not hold, is an
   unsupported coverage claim (P0) — reclassify the row `unverified`; a padded
   total is a P1 finding.
2. **Every produced file has an execution record** — file · exact command ·
   result. Re-run the produced files with that command when the harness is
   available and compare. A produced file with no record, an `unverified`
   produced file, or a `needs-fixture` e2e never run against its fixture →
   **`[unexecuted-test]`** (P0), whatever else holds; a red produced test
   (`failing`, or red on your re-run) is P0 too.
3. **Mutate or reason about ≥ 2 tested behaviours** — apply a deliberate
   mutation to the SOURCE under test (invert a guard, swallow an error, drop a
   branch), re-run, confirm the test FAILS, then restore. Guard the restore:
   before mutating, `git status --porcelain -- <file>` must be empty — if it
   is not (the author phase touched that file and the run has not committed
   it), copy the file aside and restore from the copy, never with
   `git checkout`, which would also discard the author's edit; afterwards
   `git diff --quiet -- <file>` (or a checksum) proves the tree is
   byte-identical. §7's "do not mutate test code" stands — this touches the
   SUT and is reverted. When you cannot run, name the mutation and the
   assertion line that would catch it. No nameable failing mutation →
   tautological (P0).
4. **Behaviour vs implementation** — a test that asserts internal structure,
   a mock asserting on a mock, a snapshot of a fixture, or that would still
   pass with the implementation deleted is implementation-shaped (P1); the
   detectors in §2 do not catch this — read the assertions.
5. **e2e oracles against the source** — every selector, test id and text the
   e2e waits on is rendered on the visited route under the named fixture
   (`grep` the `data-testid`, read the render rule); an oracle that can never
   match is `[scenario-defect]` (P0).
6. **Scope honesty** — the PLAN's `not covered` rows name each intent area
   without a test and why; a silent gap is a P1 finding.
7. **You never ship** — no `git push`, `gh pr create`, `gh pr merge`; the
   verdict returns to the run, whose deliver phase (or the human) opens the PR.

### Produced-test verdict (`PASS` is reachable here, unlike the audit in §5)

- **`PASS`** — all of: every `covered` claim verified at its `path:line`
  (duty 1); every produced file executed with its recorded command and green,
  and your re-run — when the harness is available — reproduces it (duty 2); no
  `unverified` and no `failing` row among the produced files; ≥ 2 behaviours
  mutated-or-reasoned with a nameable failing mutation each (duty 3); e2e
  oracles verified (duty 5); `not covered` rows account for the intent
  (duty 6); and the §2 detectors report P0 = P1 = P2 = 0 on the produced files.
- **`FAIL` with CONDITIONS** — no P0, but any P1/P2 (implementation-shaped
  test, padded total, silent scope gap, style smells): list the fixes as
  conditions above the verdict line. There is no conditional pass — the ledger
  record (§5) may still say `CONDITIONAL`; the output line says `FAIL`.
- **`FAIL`** — any P0: `[unexecuted-test]`, a red produced test, an
  unsupported `covered` claim, a tautological test, or an impossible oracle
  `[scenario-defect]`.

Report block for this mode — the §8 `AUDIT:` line stays for the audit; a
message never carries two VERDICT lines and never quotes another one. The
verdict is one plain-text line, the LAST line of your output:

```
MODE: produced-test
REVIEWER: wicked-garden-qe-test-code-quality-auditor
RUN_ID: {RUN_ID}
VERDICT: PASS|FAIL
```

## Helper resolution (`{WT_LIB}`)

`{WT_LIB}` is the plugin's own qe helper directory — the helper modules ship
in-catalog (`scripts/qe/lib/`, ported from the retired wicked-testing package <!-- historical -->
in Phase 6c). Resolve it (cross-platform):

```bash
WT_LIB="$(wicked-garden path scripts/qe/lib)"
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.