Mk vue testing best practices
Production ready. AI Agent Workflow System for Claude Code
npx -y skills add ngocsangyem/MeowKit --skill mk-vue-testing-best-practicesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Vue 3 testing best-practices review: Vitest + Vue Test Utils for components, composables, Pinia, Router, async/Suspense, forms, a11y, plus Playwright E2E strategy. Advisory only.
SKILL.md
10.9 KB, as published. Nobody here has run it
Vue Testing Best Practices
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.
When to Use
Invoke-only — this skill does NOT auto-activate. Activate it for:
the vue-testing-best-practices skill [test file or component](explicit).- "review my Vue tests", "how should I test this component/composable/store", "Vue test best practices", "Vitest or Jest for this Vue app?", "are my async component tests correct?".
Do NOT invoke for (each routes to its owner):
- Running tests / TDD red-green / non-Vue tests / generic Playwright runner protocol →
mk:testing - Diff/PR structural review or test-existence gap detection →
mk:review - Coverage→requirement mapping →
mk:nyquist - QA of a running app + bug fixes →
mk:qa - Generating or running Playwright
.spec.tsE2E →mk:qa-manual - Driving a live browser →
mk:agent-browser/mk:playwright-cli - Writing Vue feature code →
mk:vue/mk:vue-best-practices
Invocation Decision Guide
| 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 |
Disambiguation vs mk:vue-best-practices
The seam is authoring vs test-setup:
- Review how a component uses Teleport (when to use it, the API, the fallback boundary)
→
mk:vue-best-practices. - Review how a test stubs Teleport (
teleportstub,attachTo: document.body, querying portalled 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.
Testing — Problem → Reference
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 |
Workflow
Read-only advisory lifecycle. Classify the surface → load the matching reference JIT → evaluate against the rubric → emit a bounded review.
- Input — intent + the Vue test file(s) under review, or the component/composable/store the user wants to design tests for.
- Testing analysis — classify the surface: component / composable / store / router / form / async / Suspense / Teleport / E2E-design. Load the matching reference(s).
- Best-practice evaluation — apply
reference/test-smells-rubric.md: blackbox vs implementation-coupled? async awaited (flushPromises/nextTick)? Pinia configured? Suspense/Teleport set up? snapshot policy? a11y queries? brittle locators? - Gap detection — missing scenarios (error/async/edge/a11y states), test smells, Vue-specific coverage risks.
- Recommendations — concrete pattern fixes, tooling advice, and handoff notes.
- Output — a bounded Vue Testing Review (see Output Contract).
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.
Output Contract
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.
- Verdict — one line:
PASS/NEEDS-WORK+ a one-sentence why. - Test Smells — one row each:
[severity] · file:line · smell · fix. Severity vocab:critical | high | medium | low. (e.g. implementation-coupling, snapshot-only, missingawait flushPromises, missing Pinia setup, brittle CSS locator.) - Missing Scenarios — untested behaviors: error states, async/loading, edge inputs, a11y states.
- Coverage Risks — Vue-specific blind spots: Teleported content, Suspense fallback,
store actions, router guards. Note: existence-level diff coverage gaps are produced
automatically by
mk:review../review/references/test-coverage.mdduring a full review — this section audits test quality, not existence. - Tooling Recommendations — Vitest / runner (happy-dom vs Browser Mode) / library
(
@vue/test-utilsvs@testing-library/vue) / Playwright-vs-Cypress choices, each with a one-line rationale. - Handoffs — explicit next-skill pointers when applicable (execute →
mk:testing, E2E gen →mk:qa-manual, coverage map →mk:nyquist).
Worked example — design request
"How should I test this Pinia-backed
UserProfilecomponent?"
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.
Worked example — review request
"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.
Gotchas
- Missing
await flushPromises()after an API call —await nextTick()only flushes reactive DOM updates, not pending promises; an API-driven assertion runs against stale state and the test flakes. UseflushPromises()(sometimes twice for chained async). - Snapshot-only tests pass while behavior breaks — a snapshot asserts markup shape, not behavior; pair every snapshot with behavioral assertions (text/role/emitted), or it gives false confidence.
- "injection Symbol(pinia) not found" — mounting a store-backed component without
createTestingPinia(component tests) orsetActivePinia(createPinia())(store unit tests) throws on mount. Provide Pinia before asserting. - Teleported content isn't in the wrapper —
<Teleport>moves DOM out of the component subtree, sowrapper.find()misses it; stub Teleport orattachTo: document.bodyand query the document.
Reference
Provenance
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.