mk:vue-testing-best-practices — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited mk:vue-testing-best-practices (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Vue-specific test-design advisor + test-code reviewer. Recommends how to test Vue 3 components, composables, Pinia stores, Vue Router, async/Suspense, Teleport, forms, and accessibility — and audits existing Vitest + Vue Test Utils tests for smells, gaps, and coverage risk. Read-only: it advises and reviews; it never runs, generates, or fixes tests.
This skill is to mk:testing what mk:vue-best-practices is to mk:vue — a domain-specialized advisory that you invoke deliberately.
Invoke-only — this skill does NOT auto-activate. Activate it for:
/mk:vue-testing-best-practices [test file or component] (explicit).best practices", "Vitest or Jest for this Vue app?", "are my async component tests correct?".
Do NOT invoke for (each routes to its owner):
mk:testingmk:reviewmk:nyquistmk:qa.spec.ts E2E → mk:qa-manualmk:agent-browser / mk:playwright-climk:vue / mk:vue-best-practices| You want to… | Use |
|---|---|
| Write/refactor Vue feature code | mk:vue |
| Review Vue _feature_ code / authoring workflow | mk:vue-best-practices |
| Design or review Vue _test_ code; choose test tooling | this skill |
| Actually run tests / TDD loop / non-Vue tests | mk:testing |
| Diff/PR review or "does a test exist for this change?" | mk:review |
| Map test coverage → requirements (which criteria are untested) | mk:nyquist |
| "does the running site work? find + fix bugs" | mk:qa |
| Generate runnable Playwright E2E specs from a spec/URL | mk:qa-manual |
| Drive a real browser | mk:agent-browser / mk:playwright-cli |
The seam is _authoring_ vs _test-setup_:
→ mk:vue-best-practices.
teleport stub, attachTo: document.body, queryingportalled content) → this skill.
Teleport/Suspense authoring (when to use, API, fallback) → mk:vue-best-practices; Teleport/Suspense test-setup (stubs, flushPromises, attachTo, mountSuspense) → this skill.
Read one level deep from this file. Load only the reference that matches the surface.
| Problem / intent | Reference |
|---|---|
| Setting up test infrastructure for a Vue 3 project | reference/testing-vitest-recommended-for-vue.md |
| Tests break when refactoring component internals | reference/testing-component-blackbox-approach.md |
| Flaky/intermittent tests, async DOM not updated | reference/testing-async-await-flushpromises.md |
Composables using lifecycle hooks or inject fail to test | reference/testing-composables-helper-wrapper.md |
| "injection Symbol(pinia) not found" errors | reference/testing-pinia-store-setup.md |
Components with async setup() won't render | reference/testing-suspense-async-components.md |
| Snapshot tests pass despite broken functionality | reference/testing-no-snapshot-only.md |
| Choosing an end-to-end framework for a Vue app | reference/testing-e2e-playwright-recommended.md |
| Need to verify computed styles or real DOM events | reference/testing-browser-vs-node-runners.md |
defineAsyncComponent components fail in tests | reference/async-component-testing.md |
| Teleported content can't be found in wrapper queries | reference/teleport-testing-complexity.md |
Testing routing: useRoute/useRouter, navigation guards | reference/vue-router-testing.md |
| Testing forms: inputs, validation, submit payloads | reference/form-testing.md |
| Asserting accessibility in tests (roles, focus, keyboard) | reference/accessibility-testing.md |
| Reviewing tests for smells (the severity rubric) | reference/test-smells-rubric.md |
Read-only advisory lifecycle. Classify the surface → load the matching reference JIT → evaluate against the rubric → emit a bounded review.
the user wants to design tests for.
form / async / Suspense / Teleport / E2E-design. Load the matching reference(s).
reference/test-smells-rubric.md: blackbox vsimplementation-coupled? async awaited (flushPromises/nextTick)? Pinia configured? Suspense/Teleport set up? snapshot policy? a11y queries? brittle locators?
Vue-specific coverage risks.
Entry criteria: a Vue 3 project, and the user wants test design, test review, or test tooling advice.
Stop conditions (hand off, do not attempt):
| Request | Hand off to |
|---|---|
| Execute / run tests, TDD loop | mk:testing |
Generate runnable E2E .spec.ts | mk:qa-manual |
| Drive a live browser | mk:agent-browser / mk:playwright-cli |
| Coverage→requirement map | mk:nyquist |
| QA a running app + fix bugs | mk:qa |
| Diff/PR review or test-existence gaps | mk:review |
| Root-cause a failing test/bug | mk:investigate |
Escalation: non-Vue test code → mk:testing; running-app bugs → mk:qa; root-cause debugging → mk:investigate; coverage map → mk:nyquist.
Emit a single Vue Testing Review. Omit any empty section rather than padding it. Do not restate Vue basics (defer to mk:vue), dump whole files, or recite generic testing theory.
PASS / NEEDS-WORK + a one-sentence why.[severity] · file:line · smell · fix. Severity vocab:critical | high | medium | low. (e.g. implementation-coupling, snapshot-only, missing await flushPromises, missing Pinia setup, brittle CSS locator.)
a11y states.
store actions, router guards. Note: _existence-level_ diff coverage gaps are produced automatically by mk:review references/test-coverage.md during a full review — this section audits test _quality_, not existence.
(@vue/test-utils vs @testing-library/vue) / Playwright-vs-Cypress choices, each with a one-line rationale.
mk:testing,E2E gen → mk:qa-manual, coverage map → mk:nyquist).
"How should I test this Pinia-backed UserProfile component?"Verdict: NEEDS-WORK — no Pinia provided, so the component will throw on mount.
Tooling: Vitest + happy-dom; @vue/test-utils + createTestingPinia({ createSpy: vi.fn }).
Missing Scenarios: loading state, fetch error, empty profile.
Handoffs: write + run the suite → mk:testing."Review tests/SearchBar.spec.ts."Verdict: NEEDS-WORK — assertions race ahead of async DOM updates.
Test Smells:
[high] · SearchBar.spec.ts:21 · setValue not awaited · `await wrapper.find('input').setValue(...)`
[medium] · SearchBar.spec.ts:30 · brittle `.btn-primary` locator · query by role/text or data-testid
Missing Scenarios: empty-query, no-results, API error.await nextTick() only flushesreactive DOM updates, not pending promises; an API-driven assertion runs against stale state and the test flakes. Use flushPromises() (sometimes twice for chained async).
behavior; pair every snapshot with behavioral assertions (text/role/emitted), or it gives false confidence.
createTestingPinia (component tests) or setActivePinia(createPinia()) (store unit tests) throws on mount. Provide Pinia before asserting.
<Teleport> moves DOM out of the componentsubtree, so wrapper.find() misses it; stub Teleport or attachTo: document.body and query the document.
Ported and extended from an upstream Vue testing skill — see SYNC.md for the upstream path, pinned commit, and which references are vendored-verbatim vs toolkit.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.