7.1 测试策略全景
7.1.1 单元测试架构
// tests/unit/cart.store.spec.ts
import { setActivePinia, createPinia } from 'pinia'
import { useCartStore } from '@/stores/cart'
describe('购物车 Store', () => {
let store: ReturnType<typeof useCartStore>
beforeEach(() => {
setActivePinia(createPinia())
store = useCartStore()
store.$reset()
})
test('添加商品应更新购物车', () => {
const mockProduct = { id: 1, name: '商品A', price: 100 }
store.addItem(mockProduct)
expect(store.items).toHaveLength(1)
expect(store.totalPrice).toBe(100)
})
test('并发添加应触发锁定机制', async () => {
vi.useFakeTimers()
const p1 = store.safeAddItem({ id: 1 })
const p2 = store.safeAddItem({ id: 2 })
await vi.advanceTimersByTimeAsync(1000)
await expect(Promise.race([p1, p2])).rejects.toThrow('购物车已被锁定')
vi.useRealTimers()
})
})
测试金字塔策略:
- 单元测试:覆盖核心业务逻辑(覆盖率 > 80%)
- 集成测试:验证 Store 间交互(覆盖率 > 60%)
- E2E 测试:关键用户流程验证(覆盖率 > 40%)
7.2 调试高级技巧
7.2.1 时间旅行调试
// 在 Chrome DevTools 中执行
const pinia = usePinia()
// 查看状态历史
console.log(pinia._a.stateHistory)
// 回滚到指定状态
pinia._a.dispatch('timeTravel', { index: 2 })
// 录制状态变化
pinia._a.record()
7.2.2 自定义 DevTools 插件
// plugins/devtools.ts
export const customDevtoolsPlugin: PiniaPlugin = ({ store }) => {
store._customProperties = new Set()
store.$onAction(({ name, store, args }) => {
if (name === 'checkout') {
window.__VUE_DEVTOOLS_NEXT__.send({
type: 'CUSTOM_EVENT',
payload: {
type: 'checkout-started',
payload: args
}
})
}
})
}
7.3 性能监控体系
7.3.1 性能埋点方案
// plugins/performance.ts
export const performancePlugin: PiniaPlugin = ({ store }) => {
const metrics = {
actionDurations: new Map<string, number[]>(),
stateChanges: 0
}
store.$onAction(({ name }, startTime) => {
const end = performance.now()
const duration = end - startTime
if (!metrics.actionDurations.has(name)) {
metrics.actionDurations.set(name, [])
}
metrics.actionDurations.get(name)?.push(duration)
})
store.$subscribe(() => {
metrics.stateChanges++
})
window.addEventListener('beforeunload', () => {
navigator.sendBeacon('/api/performance', JSON.stringify({
storeId: store.$id,
...metrics
}))
})
}
7.3.2 内存泄漏检测
// 在开发环境添加检测
if (import.meta.env.DEV) {
const stores = new Set()
pinia.use(({ store }) => {
stores.add(store)
store.$onAction(() => {
if (stores.size > 20) {
console.warn('检测到可能的内存泄漏,当前 Store 实例数:', stores.size)
}
})
})
}
7.4 维护与迭代策略
7.4.1 状态迁移方案
// 版本化状态结构
interface CartStateV1 {
items: Array<{ id: number; qty: number }>
}
interface CartStateV2 {
items: Array<{ sku: string; quantity: number }>
}
const migrationPlugin: PiniaPlugin = ({ store }) => {
const rawState = localStorage.getItem(`pinia-${store.$id}`)
if (rawState) {
const state = JSON.parse(rawState)
// 版本检测与迁移
if (!state.version || state.version < 2) {
const migrated = migrateV1ToV2(state)
store.$patch(migrated)
}
}
}
function migrateV1ToV2(v1State: CartStateV1): CartStateV2 {
return {
version: 2,
items: v1State.items.map(item => ({
sku: `ITEM_${item.id}`,
quantity: item.qty
}))
}
}
7.4.2 弃用策略
// 使用 Proxy 实现 API 弃用警告
const deprecationPlugin: PiniaPlugin = ({ store }) => {
return new Proxy(store, {
get(target, key) {
if (key === 'oldMethod') {
console.warn('oldMethod 已弃用,请使用 newMethod 替代')
}
return Reflect.get(target, key)
}
})
}
7.5 错误追踪系统
7.5.1 Sentry 集成
// plugins/error-tracking.ts
import * as Sentry from '@sentry/vue'
export const sentryPlugin: PiniaPlugin = ({ store }) => {
store.$onAction(({ name, args, onError }) => {
onError(error => {
Sentry.withScope(scope => {
scope.setExtra('store', store.$id)
scope.setExtra('action', name)
scope.setExtra('params', args)
Sentry.captureException(error)
})
})
})
}
7.5.2 错误恢复机制
// stores/error.store.ts
defineStore('error', {
state: () => ({
retryQueue: [] as RetryableAction[]
}),
actions: {
addToRetryQueue(action: RetryableAction) {
this.retryQueue.push(action)
},
async retryAll() {
while (this.retryQueue.length > 0) {
const action = this.retryQueue.shift()!
try {
await action.handler(...action.args)
} catch (error) {
this.retryQueue.unshift(action)
throw error
}
}
}
}
})
// 使用示例
store.$onAction(({ name, args, onError }) => {
onError(error => {
useErrorStore().addToRetryQueue({
handler: store[name],
args,
retries: 3
})
})
})
本章核心总结:
- 测试体系:构建三层测试防护网,优先保证核心逻辑覆盖率
- 调试能力:
- 掌握时间旅行调试技巧
- 开发自定义 DevTools 插件
- 性能监控:
- 关键指标埋点上报
- 内存泄漏预警机制
- 维护策略:
- 版本化状态迁移方案
- API 平滑弃用方案
- 错误治理:
- 集成专业错误追踪系统
- 实现自动重试队列