测试是 Vue 应用质量保障的核心环节。Vue 生态提供了 Vue Test Utils(官方组件测试库)与 Vitest(Vite 原生测试框架)的无缝集成。本文覆盖从组件单元测试到 Playwright E2E 的完整测试体系。
一、测试环境配置
npm install -D vitest @vue/test-utils jsdom @testing-library/jest-dom
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: './tests/setup.ts',
},
})
// tests/setup.ts
import '@testing-library/jest-dom'
二、组件测试:Vue Test Utils
2.1 基础挂载与查询
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
describe('Counter', () => {
it('renders initial count', () => {
const wrapper = mount(Counter, {
props: { initial: 10 },
})
expect(wrapper.text()).toContain('10')
})
it('increments when clicked', async () => {
const wrapper = mount(Counter)
await wrapper.find('button').trigger('click')
expect(wrapper.text()).toContain('1')
})
})
2.2 Props 与 Emits 测试
it('emits update event', async () => {
const wrapper = mount(InputComponent, {
props: { modelValue: '' },
})
await wrapper.find('input').setValue('hello')
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('update:modelValue')[0]).toEqual(['hello'])
})
2.3 Slots 测试
it('renders default slot', () => {
const wrapper = mount(Modal, {
slots: {
default: '<p>Modal content</p>',
footer: '<button>OK</button>',
},
})
expect(wrapper.html()).toContain('Modal content')
})
2.4 异步组件测试
import { flushPromises } from '@vue/test-utils'
it('loads async data', async () => {
const wrapper = mount(UserProfile)
// 等待所有 Promise 解析
await flushPromises()
expect(wrapper.text()).toContain('Alice')
})
三、Pinia Store Mocking
import { setActivePinia, createPinia } from 'pinia'
import { useUserStore } from '@/stores/user'
beforeEach(() => {
setActivePinia(createPinia())
})
it('updates user state', () => {
const store = useUserStore()
store.login({ name: 'Alice' })
expect(store.isLoggedIn).toBe(true)
expect(store.user?.name).toBe('Alice')
})
四、MSW:API Mocking
// tests/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('/api/user', () => {
return HttpResponse.json({ id: '1', name: 'Alice' })
}),
]
// tests/setup.ts
import { setupServer } from 'msw/node'
import { handlers } from './mocks/handlers'
const server = setupServer(...handlers)
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
五、Playwright E2E
import { test, expect } from '@playwright/test'
test('user login flow', async ({ page }) => {
await page.goto('/login')
await page.fill('[name="email"]', 'test@example.com')
await page.fill('[name="password"]', 'password')
await page.click('button[type="submit"]')
await expect(page).toHaveURL('/dashboard')
})
六、CI 集成
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run test:unit -- --coverage
- run: npm run test:e2e
相关阅读
- Vue 详解 — 核心概念
- Vue Composition API 完全指南 — Composition API 测试模式
- React 测试指南 — 跨框架测试对比
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。
「frontend」更多文章
Vue 性能优化指南:虚拟列表、懒加载、渲染优化与 Core Web Vitals
Vue 3 应用性能优化完整策略:虚拟滚动(vue-virtual-scroller)、组件懒加载与异步组件、KeepAlive 缓存、Suspense 异步优化、v-memo 渲染记忆化、响应式性能(shallowRef/toRaw)、Bundle 分析与代码分割、渲染函数优化、以及 Core Web Vitals(LCP/INP/CLS)调优。
Nuxt.js 完全指南:Vue 全栈框架的 SSR、SSG、API 路由与部署实践
Nuxt.js 3 深度实践:文件系统路由、SSR/SSG/ISR 渲染模式、API 路由(Server Routes)、useFetch/useAsyncData 数据获取、中间件与插件、SEO 与 Meta 管理、Nitro 服务端引擎、自动导入、部署到 Vercel/Netlify/Node.js。
Vue + TypeScript 深度实战:组件类型、Props 泛型、Pinia 类型安全与 API 契约
Vue 3 与 TypeScript 结合的生产级实践:组件 Props 类型标注、defineProps 泛型、 emits 类型、ref/reactive 类型推断、computed 类型、Pinia Store 类型、Vue Router 类型安全、Zod API 数据契约、以及 strict tsconfig 配置。