feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
---
|
||||
title: Use Vitest for Vue 3 Testing - Recommended by Vue Team
|
||||
impact: MEDIUM
|
||||
impactDescription: Using Jest or other runners with Vite projects requires complex configuration and causes slower test runs
|
||||
type: best-practice
|
||||
tags: [vue3, testing, vitest, vite, configuration, setup]
|
||||
---
|
||||
|
||||
# Use Vitest for Vue 3 Testing - Recommended by Vue Team
|
||||
|
||||
**Impact: MEDIUM** - Vitest is created and maintained by Vue/Vite team members and shares the same configuration and transform pipeline as Vite. Using Jest or other test runners with Vite-based projects requires additional configuration and can result in slower test execution and compatibility issues.
|
||||
|
||||
Use Vitest for new Vue 3 projects. Only consider Jest if migrating an existing test suite.
|
||||
|
||||
## Task Checklist
|
||||
|
||||
- [ ] Install Vitest and related packages for Vue testing
|
||||
- [ ] Configure vitest in vite.config.js or vitest.config.js
|
||||
- [ ] Set up proper test environment (happy-dom or jsdom)
|
||||
- [ ] Add test scripts to package.json
|
||||
- [ ] Configure globals if desired for cleaner test syntax
|
||||
- [ ] Use @vue/test-utils for component mounting
|
||||
|
||||
## Quick Setup
|
||||
|
||||
```bash
|
||||
# Install required packages
|
||||
npm install -D vitest @vue/test-utils happy-dom
|
||||
# or with jsdom
|
||||
npm install -D vitest @vue/test-utils jsdom
|
||||
```
|
||||
|
||||
**vite.config.js:**
|
||||
```javascript
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
test: {
|
||||
// Enable global test APIs (describe, it, expect)
|
||||
globals: true,
|
||||
// Use happy-dom for faster tests (or 'jsdom' for better compatibility)
|
||||
environment: 'happy-dom',
|
||||
// Optional: Setup files for global configuration
|
||||
setupFiles: ['./src/test/setup.js']
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
**package.json:**
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"test": "vitest",
|
||||
"test:run": "vitest run",
|
||||
"test:coverage": "vitest run --coverage"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**tsconfig.json (if using TypeScript):**
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["vitest/globals"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Test File Example
|
||||
|
||||
```javascript
|
||||
// src/components/Counter.test.js
|
||||
import { describe, it, expect, beforeEach } from 'vitest' // optional with globals: true
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Counter from './Counter.vue'
|
||||
|
||||
describe('Counter', () => {
|
||||
let wrapper
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(Counter)
|
||||
})
|
||||
|
||||
it('renders initial count', () => {
|
||||
expect(wrapper.find('[data-testid="count"]').text()).toBe('0')
|
||||
})
|
||||
|
||||
it('increments when button clicked', async () => {
|
||||
await wrapper.find('[data-testid="increment"]').trigger('click')
|
||||
expect(wrapper.find('[data-testid="count"]').text()).toBe('1')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Vitest vs Jest Comparison
|
||||
|
||||
| Feature | Vitest | Jest |
|
||||
|---------|--------|------|
|
||||
| Vite Integration | Native | Requires config |
|
||||
| Speed | Very fast (ESM native) | Slower with Vite |
|
||||
| Watch Mode | Excellent | Good |
|
||||
| Vue SFC Support | Works with Vite | Needs vue-jest |
|
||||
| Config Sharing | Same as vite.config | Separate |
|
||||
| API | Jest-compatible | Standard |
|
||||
|
||||
## Using with Testing Library
|
||||
|
||||
```bash
|
||||
npm install -D @testing-library/vue @testing-library/jest-dom
|
||||
```
|
||||
|
||||
```javascript
|
||||
// src/test/setup.js
|
||||
import { expect } from 'vitest'
|
||||
import * as matchers from '@testing-library/jest-dom/matchers'
|
||||
|
||||
expect.extend(matchers)
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Component.test.js
|
||||
import { render, screen, fireEvent } from '@testing-library/vue'
|
||||
import UserCard from './UserCard.vue'
|
||||
|
||||
test('displays user name', () => {
|
||||
render(UserCard, {
|
||||
props: { name: 'John Doe' }
|
||||
})
|
||||
|
||||
expect(screen.getByText('John Doe')).toBeInTheDocument()
|
||||
})
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
```javascript
|
||||
// vitest.config.js (separate file if preferred)
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'happy-dom',
|
||||
include: ['**/*.{test,spec}.{js,ts,jsx,tsx}'],
|
||||
exclude: ['node_modules', 'dist', 'e2e'],
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'json', 'html'],
|
||||
exclude: ['node_modules', 'test']
|
||||
},
|
||||
// Helpful for debugging
|
||||
reporters: ['verbose'],
|
||||
// Run tests in sequence in CI
|
||||
poolOptions: {
|
||||
threads: {
|
||||
singleThread: process.env.CI === 'true'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Mocking Modules
|
||||
```javascript
|
||||
import { vi } from 'vitest'
|
||||
|
||||
vi.mock('@/api/users', () => ({
|
||||
fetchUser: vi.fn().mockResolvedValue({ name: 'John' })
|
||||
}))
|
||||
```
|
||||
|
||||
### Testing with Fake Timers
|
||||
```javascript
|
||||
import { vi, beforeEach, afterEach } from 'vitest'
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
test('debounced search', async () => {
|
||||
const wrapper = mount(SearchBox)
|
||||
await wrapper.find('input').setValue('vue')
|
||||
|
||||
vi.advanceTimersByTime(300)
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.emitted('search')).toBeTruthy()
|
||||
})
|
||||
```
|
||||
|
||||
## Reference
|
||||
- [Vitest Documentation](https://vitest.dev/)
|
||||
- [Vue.js Testing Guide](https://vuejs.org/guide/scaling-up/testing)
|
||||
- [Vue Test Utils](https://test-utils.vuejs.org/)
|
||||
Reference in New Issue
Block a user