Resources
3Install
npx skillscat add pluginagentmarketplace/custom-plugin-vue/vue-testing Install via the SkillsCat registry.
This skill teaches comprehensive testing strategies for Vue applications using Vitest, Vue Test Utils, and Playwright. It covers unit, component, integration, and end-to-end testing through structured learning modules with practical exercises and configuration examples. Developers should use it when building or maintaining Vue applications that require systematic test coverage across all testing layers.
Vue Testing Skill
Production-grade skill for mastering Vue application testing with Vitest, Vue Test Utils, and Playwright.
Purpose
Single Responsibility: Teach comprehensive testing strategies for Vue applications including unit, component, integration, and E2E testing.
Parameter Schema
interface VueTestingParams {
topic: 'unit' | 'component' | 'integration' | 'e2e' | 'mocking' | 'all';
level: 'beginner' | 'intermediate' | 'advanced';
context?: {
test_runner?: 'vitest' | 'jest';
e2e_tool?: 'playwright' | 'cypress';
coverage_target?: number;
};
}Learning Modules
Module 1: Testing Fundamentals
Prerequisites: vue-fundamentals
Duration: 2 hours
Outcome: Set up testing environment| Topic | Tool | Exercise |
|---|---|---|
| Setup | Vitest + VTU | Configure project |
| Test structure | describe/it/expect | First test |
| Assertions | expect matchers | Various assertions |
| Test naming | Descriptive names | Convention practice |
Vitest Configuration:
// vitest.config.ts
export default defineConfig({
plugins: [vue()],
test: {
globals: true,
environment: 'jsdom',
coverage: {
provider: 'v8',
thresholds: { lines: 80 }
}
}
})Module 2: Component Testing
Prerequisites: Module 1
Duration: 4-5 hours
Outcome: Test Vue components thoroughly| Test Type | What to Test | Example |
|---|---|---|
| Rendering | DOM output | Text content |
| Props | Input handling | Prop values |
| Events | Emitted events | Button clicks |
| Slots | Slot content | Custom content |
| Async | Loading states | API responses |
Component Test Template:
import { mount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'
describe('MyComponent', () => {
it('renders correctly', () => {
const wrapper = mount(MyComponent, {
props: { title: 'Test' }
})
expect(wrapper.text()).toContain('Test')
})
it('emits event on click', async () => {
const wrapper = mount(MyComponent)
await wrapper.find('button').trigger('click')
expect(wrapper.emitted('action')).toHaveLength(1)
})
})Module 3: Mocking Strategies
Prerequisites: Module 2
Duration: 3 hours
Outcome: Mock dependencies effectively| Mock Type | Use Case | Example |
|---|---|---|
| Modules | API services | vi.mock() |
| Composables | Custom hooks | Return mocks |
| Timers | Debounce/setTimeout | vi.useFakeTimers() |
| HTTP | API calls | MSW or vi.mock |
| Router | Navigation | Mock router |
| Store | Pinia stores | createTestingPinia |
Module 4: Testing Composables & Stores
Prerequisites: Module 3
Duration: 3 hours
Outcome: Test reusable logicComposable Testing:
import { useCounter } from './useCounter'
it('increments count', () => {
const { count, increment } = useCounter()
increment()
expect(count.value).toBe(1)
})Store Testing:
import { setActivePinia, createPinia } from 'pinia'
import { useUserStore } from './useUserStore'
beforeEach(() => setActivePinia(createPinia()))
it('logs in user', async () => {
const store = useUserStore()
await store.login(credentials)
expect(store.isLoggedIn).toBe(true)
})Module 5: E2E Testing with Playwright
Prerequisites: Modules 1-4
Duration: 4 hours
Outcome: Write reliable E2E tests| Concept | Playwright API | Exercise |
|---|---|---|
| Navigation | page.goto() | Page visits |
| Selectors | getByRole() | Element selection |
| Actions | click(), fill() | User interactions |
| Assertions | expect().toBeVisible() | Verify state |
| Fixtures | test.use() | Reusable setup |
Playwright Test:
import { test, expect } from '@playwright/test'
test.describe('Login', () => {
test('logs in successfully', async ({ page }) => {
await page.goto('/login')
await page.getByLabel('Email').fill('user@example.com')
await page.getByLabel('Password').fill('password')
await page.getByRole('button', { name: 'Submit' }).click()
await expect(page).toHaveURL('/dashboard')
await expect(page.getByText('Welcome')).toBeVisible()
})
})Validation Checkpoints
Beginner Checkpoint
- Set up Vitest with Vue
- Write basic component test
- Test props and events
- Run tests with coverage
Intermediate Checkpoint
- Mock API calls
- Test async components
- Test composables
- Test Pinia stores
Advanced Checkpoint
- Write E2E tests with Playwright
- Achieve 80%+ coverage
- Test edge cases
- Set up CI testing
Retry Logic
const skillConfig = {
maxAttempts: 3,
backoffMs: [1000, 2000, 4000],
onFailure: 'provide_test_hint'
}Observability
tracking:
- event: test_written
data: [test_type, component_name]
- event: coverage_achieved
data: [percentage, file_count]
- event: skill_completed
data: [tests_written, coverage]Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| wrapper.vm undefined | shallowMount used | Use mount() |
| Mock not working | Wrong vi.mock path | Match import path |
| Async not resolved | Missing await | Await async ops |
| Flaky E2E | Race conditions | Add proper waits |
Debug Steps
- Check test isolation (beforeEach cleanup)
- Verify mock is at file top
- Console.log wrapper.html()
- Use Playwright trace viewer
Unit Test Template
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount, VueWrapper } from '@vue/test-utils'
import Component from './Component.vue'
describe('Component', () => {
let wrapper: VueWrapper
beforeEach(() => {
wrapper = mount(Component, {
props: {},
global: {
stubs: {},
mocks: {},
plugins: []
}
})
})
it('renders correctly', () => {
expect(wrapper.exists()).toBe(true)
})
it('handles user interaction', async () => {
await wrapper.find('button').trigger('click')
expect(wrapper.emitted('action')).toBeTruthy()
})
})Usage
Skill("vue-testing")Related Skills
vue-fundamentals- Prerequisitevue-composition-api- For composable testingvue-pinia- For store testing