Load when writing or reviewing unit, integration, end-to-end, visual, or accessibility tests. Owns layer selection, placement, naming, mocking discipline, coverage targets, security-regression TDD cases, the green-but-lying traps, and theme-matrix visual and a11y patterns. Frameworks and commands come from the Project Profile.
Skill: Testing Architect — Test Strategy & Authoring
Apply Guidelines Skill — load the guidelines-meta skill before proceeding.
Profile section owned: §Conventions (test layers, placement, coverage bar) (Guidelines §5.1–§5.4). If the project has no tests yet, propose the layer set and placement, and record them once agreed.
Operational Constraints (Strict — restated from Guidelines)
Git and golden-file guards are enforced by the plugin's PreToolUse hook (Guidelines §9, §10): every git write, gh publish, --no-verify, and snapshot update is denied by the runtime; read-only inspection stays open.
Tests are part of the deliverable (§11) — no "tests TBD", no merge-ready code without paired tests.
Never weaken a test to make it pass. Loosening a tolerance, deleting an assertion, adding a skip, or widening a mock to swallow the failure is a defect. Fix the code or surface the disagreement.
0. Resolve the Layers First
Read the profile and write down what actually exists here. Everything below applies to whichever of these the project has; a layer with no tooling is n-a, not a reason to invent one.
Companion docs: if the profile names a test-tooling doc or a suite-inventory doc, keep them in sync when strategy changes. This skill is the authoring procedure; those are the reference.
1. Unit Tests
Placement & Naming
Follow the project's existing convention (spec beside the source, or a mirrored tests/ tree) — read a sibling test before creating a new file.
One describe per public API; one test per observable behavior, named in plain English ('sets the id and timestamp', never 'test1' or 'should work').
Setup Pattern
Build the unit through the project's normal construction path (DI container, factory, framework test harness) so the graph mirrors runtime. Avoid hand-instantiating when the app doesn't.
Provide real collaborators where the unit-under-test owns the contract; mock only at I/O boundaries — network, filesystem, database, clock, randomness, navigation.
Never mock the unit's own helpers. That tests your mocks.
What to Cover
Happy path — the documented behavior.
Edge cases — empty input, missing optional fields, boundary values (test both sides of every bound).
Error paths — invalid input, rejection, validator failure, and what the user sees when it happens.
Security regression — see §2. Only when the change actually reaches such a sink; most changes reach none, and saying so is a complete answer.
Coverage target: the profile's bar (commonly 100% branch on new functions). If a branch is genuinely untestable (a defensive never return), justify it in one inline comment and move on.
Anti-patterns to Reject
Vague names that describe the code instead of the behavior.
Real sleeps/setTimeout waits — use the framework's fake timers or an explicit completion signal.
Assertions on implementation details (call counts of private helpers) instead of outcomes.
Snapshot-serializing large objects in unit tests to avoid deciding what matters. Visual comparison is the visual layer's job.
A test that passes whether or not the feature works. If deleting the implementation doesn't fail the test, the test is decoration.
2. Security-Regression Cases (TDD for the threat model)
What to test against comes from the module-threat-model skill — its references/regression-targets.md lists the sinks worth a regression test and its §1 names the category. How the test is built, where it lives, and what it asserts is this skill's job. The pairing rule is one-directional: the test must fail against the unpatched code. A security test that passes before the fix is asserting the happy path with a scary name.
A finding from Code Review Architect's security pass is closed with a failing-first test exercising the malicious input, then the fix — not just a hardened line. Name the test by the attack, not by the fix.
This applies only when the change actually reaches such a sink; most changes reach none, and saying so is a complete answer. Keep these as ordinary tests in the project's existing framework. No new tooling.
3. Trusting a Green Run
A passing suite is evidence about the suite, not about the feature. The named failure modes — the fake-timer flush illusion, compiler-silenced fixtures, hand-maintained test doubles, gates with structural blind spots, a scan mistaken for accessibility, and a test that passes with the implementation deleted — live in the module-gate-battery skill §3. Check them by name before calling a green run proof of anything.
4. What to Read, and When
Read
When
${CLAUDE_SKILL_DIR}/references/e2e-visual.md
Authoring an e2e or visual spec — helpers, selectors, screenshot naming, theme matrix.
${CLAUDE_SKILL_DIR}/references/a11y-tests.md
Authoring accessibility coverage — the two required layers and the triage order.
Asserting focus destination and announcement — the barriers no scan reports.
5. Verification (when invoked from Implementing Architect)
Run the profile's gates per the module-gate-battery skill — its order, its one-batch rule, its result table. Then manual review by the user, then a manual smoke of the running app if the change is user-visible. Stay within the bounded-passes ceiling (Guidelines §16).
Quality Checklist Before Claiming "Tests Done"
Every new/changed public function has a spec covering happy, edge, and error paths.
Any change reaching an import/deserialization, injection, consent, authz/IDOR, or path sink has a failing-first security-regression spec named by the attack — or is explicitly stated to reach none.
Coverage meets the profile's bar on new code, or each gap has a one-line justification.
Checked for the green-but-lying traps (§3): no fake-timer flush illusion, no compiler-silenced stale fixture, every test double updated for new methods, blind-spot gates verified past.
Every UI-visible change has visual coverage in all themes across the relevant device/browser projects.
Every UI-visible change has a11y coverage in all themes (rule scan + keyboard walk).
Any new overlay, async status, or client-side route change asserts its focus destination and its announcement — the barriers no scan reports (module-operability-floor §2–§3).
Visual specs use the project's helpers — no inline seeding, auth, consent, or theming.
Selectors anchor on component tags or stable test attributes — never styling classes.
No test was weakened (tolerance loosened, assertion deleted, skip added) to get green.
No git add, git commit, git push, git checkout, or --no-verify was ever issued.
If baselines failed, they are surfaced for manual review — not auto-updated.
When to Use This Skill
Cited by Planning Architect when filling the test columns of a plan.
Cited by Implementing Architect when authoring or extending tests under an approved plan.
Direct invocation: "Use Testing Architect" — to review or upgrade an existing area's suite without a fresh plan.
v2.0 — version history in CHANGELOG.md
1---2name: testing-architect3description: Load when writing or reviewing unit, integration, end-to-end, visual, or accessibility tests. Owns layer selection, placement, naming, mocking discipline, coverage targets, security-regression TDD cases, the green-but-lying traps, and theme-matrix visual and a11y patterns. Frameworks and commands come from the Project Profile.4---56# Skill: Testing Architect — Test Strategy & Authoring78> **Apply Guidelines Skill** — load the `guidelines-meta` skill before proceeding.9> **Profile section owned:** §Conventions (test layers, placement, coverage bar) (Guidelines §5.1–§5.4). If the project has no tests yet, propose the layer set and placement, and record them once agreed.1011---1213## Operational Constraints (Strict — restated from Guidelines)14151. **Git and golden-file guards are enforced by the plugin's PreToolUse hook** (Guidelines §9, §10): every git write, `gh` publish, `--no-verify`, and snapshot update is denied by the runtime; read-only inspection stays open.162. **Tests are part of the deliverable** (§11) — no "tests TBD", no merge-ready code without paired tests.173. **Never weaken a test to make it pass.** Loosening a tolerance, deleting an assertion, adding a skip, or widening a mock to swallow the failure is a defect. Fix the code or surface the disagreement.1819---2021## 0. Resolve the Layers First2223Read the profile and write down what actually exists here. Everything below applies to whichever of these the project has; a layer with no tooling is `n-a`, not a reason to invent one.2425| Layer | Purpose | Resolved from profile |26|---|---|---|27| **Unit** | One unit's behavior, isolated at I/O boundaries | framework, command, file placement |28| **Integration** | Real collaborators wired together | framework, command |29| **E2E** | User-visible flows in a real runtime | framework, command, device/browser matrix |30| **Visual / golden** | Rendered output vs. approved baseline | command, tolerance, report path, **user-only** update command |31| **Accessibility** | Automated rule scan + keyboard traversal | command, rule tags, exclusions |32| **Static** | Types, lint | commands |3334**Companion docs:** if the profile names a test-tooling doc or a suite-inventory doc, keep them in sync when strategy changes. This skill is the authoring procedure; those are the reference.3536---3738## 1. Unit Tests3940### Placement & Naming41- Follow the project's existing convention (spec beside the source, or a mirrored `tests/` tree) — read a sibling test before creating a new file.42- One `describe` per public API; one test per observable behavior, named in plain English (`'sets the id and timestamp'`, never `'test1'` or `'should work'`).4344### Setup Pattern45- Build the unit through the project's normal construction path (DI container, factory, framework test harness) so the graph mirrors runtime. Avoid hand-instantiating when the app doesn't.46- Provide **real** collaborators where the unit-under-test owns the contract; **mock only at I/O boundaries** — network, filesystem, database, clock, randomness, navigation.47- Never mock the unit's own helpers. That tests your mocks.4849### What to Cover50- **Happy path** — the documented behavior.51- **Edge cases** — empty input, missing optional fields, boundary values (test *both* sides of every bound).52- **Error paths** — invalid input, rejection, validator failure, and what the user sees when it happens.53- **Security regression** — see §2. Only when the change actually reaches such a sink; most changes reach none, and saying so is a complete answer.54- **Coverage target:** the profile's bar (commonly 100% branch on new functions). If a branch is genuinely untestable (a defensive `never` return), justify it in one inline comment and move on.5556### Anti-patterns to Reject57- Vague names that describe the code instead of the behavior.58- Real sleeps/`setTimeout` waits — use the framework's fake timers or an explicit completion signal.59- Assertions on implementation details (call counts of private helpers) instead of outcomes.60- Snapshot-serializing large objects in unit tests to avoid deciding what matters. Visual comparison is the visual layer's job.61- A test that passes whether or not the feature works. If deleting the implementation doesn't fail the test, the test is decoration.6263---6465## 2. Security-Regression Cases (TDD for the threat model)6667> **What to test against comes from the `module-threat-model` skill** — its `references/regression-targets.md` lists the sinks worth a regression test and its §1 names the category. How the test is built, where it lives, and what it asserts is this skill's job. The pairing rule is one-directional: the test must **fail against the unpatched code**. A security test that passes before the fix is asserting the happy path with a scary name.6869A finding from Code Review Architect's security pass is closed with a **failing-first test exercising the malicious input**, then the fix — not just a hardened line. Name the test by the attack, not by the fix.7071This applies only when the change actually reaches such a sink; most changes reach none, and saying so is a complete answer. Keep these as ordinary tests in the project's existing framework. No new tooling.7273## 3. Trusting a Green Run7475A passing suite is evidence about the suite, not about the feature. The named failure modes — the fake-timer flush illusion, compiler-silenced fixtures, hand-maintained test doubles, gates with structural blind spots, a scan mistaken for accessibility, and a test that passes with the implementation deleted — live in the `module-gate-battery` skill §3. Check them by name before calling a green run proof of anything.7677## 4. What to Read, and When7879| Read | When |80|---|---|81| `${CLAUDE_SKILL_DIR}/references/e2e-visual.md` | Authoring an e2e or visual spec — helpers, selectors, screenshot naming, theme matrix. |82| `${CLAUDE_SKILL_DIR}/references/a11y-tests.md` | Authoring accessibility coverage — the two required layers and the triage order. |83| `${CLAUDE_SKILL_DIR}/references/test-plan-output.md` | Filling a plan's `Tests:` lines from `planning-architect`. |84| `module-threat-model` → `references/regression-targets.md` | A change reaches a security sink. |85| `module-gate-battery` | Running or trusting a green suite. |86| `module-operability-floor` | Asserting focus destination and announcement — the barriers no scan reports. |8788---8990## 5. Verification (when invoked from Implementing Architect)9192Run the profile's gates per the `module-gate-battery` skill — its order, its one-batch rule, its result table. Then **manual** review by the user, then a manual smoke of the running app if the change is user-visible. Stay within the bounded-passes ceiling (Guidelines §16).9394## Quality Checklist Before Claiming "Tests Done"9596- [ ] Every new/changed public function has a spec covering happy, edge, and error paths.97- [ ] Any change reaching an import/deserialization, injection, consent, authz/IDOR, or path sink has a **failing-first security-regression** spec named by the attack — or is explicitly stated to reach none.98- [ ] Coverage meets the profile's bar on new code, or each gap has a one-line justification.99- [ ] Checked for the green-but-lying traps (§3): no fake-timer flush illusion, no compiler-silenced stale fixture, every test double updated for new methods, blind-spot gates verified past.100- [ ] Every UI-visible change has visual coverage in **all** themes across the relevant device/browser projects.101- [ ] Every UI-visible change has a11y coverage in all themes (rule scan + keyboard walk).102- [ ] Any new overlay, async status, or client-side route change asserts its focus destination and its announcement — the barriers no scan reports (`module-operability-floor` §2–§3).103- [ ] Visual specs use the project's helpers — no inline seeding, auth, consent, or theming.104- [ ] Selectors anchor on component tags or stable test attributes — never styling classes.105- [ ] No test was weakened (tolerance loosened, assertion deleted, skip added) to get green.106- [ ] No `git add`, `git commit`, `git push`, `git checkout`, or `--no-verify` was ever issued.107- [ ] If baselines failed, they are surfaced for manual review — **not** auto-updated.108109---110111## When to Use This Skill112113- Cited by **Planning Architect** when filling the test columns of a plan.114- Cited by **Implementing Architect** when authoring or extending tests under an approved plan.115- Direct invocation: "Use Testing Architect" — to review or upgrade an existing area's suite without a fresh plan.116117---118119_v2.0 — version history in CHANGELOG.md_
Run npx skillmds@latest add matis-dev/testing-architect in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Load when writing or reviewing unit, integration, end-to-end, visual, or accessibility tests. Owns layer selection, placement, naming, mocking discipline, coverage targets, security-regression TDD cases, the green-but-lying traps, and theme-matrix visual and a11y patterns. Frameworks and commands come from the Project Profile. It is listed under Web & Frontend on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
matis-dev (@matis-dev) published this skill. Their other Agent Skills are listed on their SkillMD profile.