Test Pyramid Check: $ARGUMENTS
Audit whether $ARGUMENTS (a feature or module) carries the test tiers it should, and whether its E2E tier follows the disciplines the spec requires. This skill reads and reports — it generates and modifies nothing.
Implements the closed functional-tier taxonomy of spec/project/test-pyramid-foundation/ (tier completeness) and the E2E-discipline requirements of spec/project/e2e-test-automation/. The foundation owns coverage governance — coverage is a guide, not a target — so read any project-declared coverage targets from the project rather than assuming a number.
German trigger phrases
Also triggers on equivalent German-language requests, including "Testpyramide prüfen", "Teststufen-Vollständigkeit auditieren", "prüfe ob alle Testebenen vorhanden sind". Detect the user's language and respond in it; the report table uses English headers so it stays diffable.
Operations
1. Read the spec and detect the stack
Read spec/project/test-pyramid-foundation/ (the closed functional-tier taxonomy), spec/project/e2e-test-automation/ (the E2E disciplines), and spec/project/test-falsifiability/ (the T-categories behind operation 5). Detect the project's stack from its manifests and layout (e.g. pyproject.toml + tests/, package.json + *.test.ts, go.mod + *_test.go) so you glob the right paths for each tier. Read the project's declared coverage targets where they live (CI config, pyproject.toml [tool.coverage], a project test spec) — do not assume a fixed percentage.
2. Locate each tier (in parallel)
Glob the test files for $ARGUMENTS across the applicable tiers, scoping by the feature/module name. Map each to a tier:
| Tier | Scope | Typical signal |
|---|---|---|
| Unit | one unit of behaviour in isolation | unit test files next to / mirroring the module |
| Component | a single shippable component in isolation (externals doubled) | component / render test files; service-in-isolation tests |
| Integration | code against one real external collaborator | integration test dir, Testcontainers, DB fixtures |
| Contract | a service-boundary agreement, no live partner | contract / pact test files (only where a service boundary exists) |
| E2E | user journeys through the real UI | the E2E suite (reference profile: tests/e2e/) |
These are the foundation's functional tiers above static analysis. The static-analysis tier (lint / type-check / format) is audited by the quality gate, not here. A tier that does not apply (no service boundary → no contract tier; no UI → no E2E) is not a gap; record it as n/a with the reason.
3. Check fast-tier gating
Confirm the fast tiers exist for $ARGUMENTS's business logic, and that a coverage gate is actually wired (CI fails below the project's declared floor) rather than merely aspirational. Report the declared target and whether it is enforced — not a number you invented.
4. Check E2E discipline
If an E2E tier exists for $ARGUMENTS, check it against the spec's disciplines (grep-level, not a deep code review — that is e2e-test-reviewer):
- Page-object encapsulation — no raw driver element-lookups in test bodies
- Condition-based waits — no fixed-duration sleeps in tests
- Screenshot checkpoints present
- At least one marker per test
- TC-ID traceability in docstrings
Flag violations by file; for a deep per-line review or repairs, hand off to e2e-test-reviewer.
5. Flag falsifiability suspects
Per spec/project/test-falsifiability/, a tier whose tests can't fail isn't coverage. Sweep each located tier at grep level (not a deep review — that is the owning tier reviewer's falsifiability dimension):
- Empty exception handlers in test files — an
except/catchwhose body is onlypass/empty (T1) - Tautological assertions —
assert True, comparisons true for every value such as>= 0on a count or length (T2) - Assertions consisting solely of a negative ("no error shown") with no paired positive assertion (T2)
- Duplicate selector values under differently named locator constants in E2E page objects (T6)
- Test functions whose body holds no assertion statement and no call to an asserting helper, and assertions sitting after an unconditional early return (T8) — a documented smoke test naming that contract is exempt
Flag each hit by file with its T-category, exclude flagged tests from every tier's effective count in the report, and route each hit to the owning tier reviewer for the graded review.
6. Report
# Test pyramid review: {feature/module}
## Tier overview
| Tier | Present | Tests | Assessment |
|------|---------|-------|------------|
| Unit | yes/no/n-a | N | ... |
| Component | yes/no/n-a | N | ... |
| Integration | yes/no/n-a | N | ... |
| Contract | yes/no/n-a | N | ... |
| E2E | yes/no/n-a | N | ... |
## Fast-tier gating
{declared target, enforced yes/no, source}
## E2E discipline
{page objects / waits / screenshots / markers / TC-IDs — per check, with file refs}
## Falsifiability suspects
{per tier: file + T-category per spec/project/test-falsifiability/, or "none found"; flagged tests are excluded from the Tier overview's effective counts and routed to the owning tier reviewer}
## Gaps (prioritised)
{numbered list of missing tiers / ungated coverage / discipline violations}
## Verdict
{spec-conformant, or N gaps — with the highest-priority gap named}
Hard rules
- Read and report only — never scaffold, edit, or run tests. Scaffolding is
e2e-test-generator; repair ise2e-test-reviewer; running the gate isquality-gate. - A non-applicable tier is
n/awith a reason, never a gap — don't demand an API tier from a system with no API. - Report the project's declared coverage target and whether it is enforced; never invent a percentage.
- Keep the E2E check at grep/structure level; route deep review and fixes to
e2e-test-reviewer. The falsifiability sweep is grep-level too: suspects route to the owning tier reviewer for the named-dimension grading, and a flagged suspect never counts toward a tier's effective coverage. - When
spec/project/test-pyramid-foundation/(tier taxonomy / completeness),spec/project/e2e-test-automation/(E2E discipline), orspec/project/test-falsifiability/(falsifiability sweep) and this skill disagree, the spec wins; this skill needs the update.
Why this is a skill, not an agent
- Orchestration role: tier auditing is one step in a pre-release / post-feature flow; the gap report is meant to flow back into the conversation so the caller decides which gaps to close.
- Interactivity: the caller typically triages the gaps (fill now, defer) in the same conversation — skill bias.
- Context-window impact is acceptable: the work is glob + grep + a compact table, so subagent isolation would not pay for itself.
- Counter-dimension (context-window, which favours an agent): a very large suite means many file reads, but they are shallow (globs and greps, not full reads), so the volume stays manageable in-thread.