基于项目需求文档(PRD.md, FeatureSummary.md, DevelopmentPlan.md, UIDesign.md, User_Role_Interfaces.md)编写的 TDD 测试用例。 后端测试 (Python/pytest): - 单元测试: rule_engine, brief_parser, timestamp_alignment, video_auditor, validators - 集成测试: API Brief, Video, Review 端点 - AI 模块测试: ASR, OCR, Logo 检测服务 - 全局 fixtures 和 pytest 配置 前端测试 (TypeScript/Vitest): - 工具函数测试: utils.test.ts - 组件测试: Button, VideoPlayer, ViolationList - Hooks 测试: useVideoAudit, useVideoPlayer, useAppeal - MSW mock handlers 配置 E2E 测试 (Playwright): - 认证流程测试 - 视频上传流程测试 - 视频审核流程测试 - 申诉流程测试 所有测试当前使用 pytest.skip() / it.skip() 作为占位符, 遵循 TDD 红灯阶段 - 等待实现代码后运行。 验收标准覆盖: - ASR WER ≤ 10% - OCR 准确率 ≥ 95% - Logo F1 ≥ 0.85 - 时间戳误差 ≤ 0.5s - 频次统计准确率 ≥ 95% Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
/**
|
|
* 前端测试全局设置
|
|
*
|
|
* 配置 MSW (Mock Service Worker) 和测试工具
|
|
*/
|
|
|
|
import '@testing-library/jest-dom'
|
|
import { afterAll, afterEach, beforeAll, vi } from 'vitest'
|
|
// import { server } from './mocks/server'
|
|
|
|
// MSW 服务器设置
|
|
// beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
|
|
// afterEach(() => server.resetHandlers())
|
|
// afterAll(() => server.close())
|
|
|
|
// Mock window.matchMedia
|
|
Object.defineProperty(window, 'matchMedia', {
|
|
writable: true,
|
|
value: vi.fn().mockImplementation((query: string) => ({
|
|
matches: false,
|
|
media: query,
|
|
onchange: null,
|
|
addListener: vi.fn(),
|
|
removeListener: vi.fn(),
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
dispatchEvent: vi.fn(),
|
|
})),
|
|
})
|
|
|
|
// Mock IntersectionObserver
|
|
class MockIntersectionObserver implements IntersectionObserver {
|
|
readonly root: Element | null = null
|
|
readonly rootMargin: string = ''
|
|
readonly thresholds: ReadonlyArray<number> = []
|
|
|
|
constructor(
|
|
private callback: IntersectionObserverCallback,
|
|
_options?: IntersectionObserverInit
|
|
) {}
|
|
|
|
observe(_target: Element): void {}
|
|
unobserve(_target: Element): void {}
|
|
disconnect(): void {}
|
|
takeRecords(): IntersectionObserverEntry[] {
|
|
return []
|
|
}
|
|
}
|
|
|
|
window.IntersectionObserver = MockIntersectionObserver
|
|
|
|
// Mock ResizeObserver
|
|
class MockResizeObserver implements ResizeObserver {
|
|
constructor(_callback: ResizeObserverCallback) {}
|
|
observe(_target: Element, _options?: ResizeObserverOptions): void {}
|
|
unobserve(_target: Element): void {}
|
|
disconnect(): void {}
|
|
}
|
|
|
|
window.ResizeObserver = MockResizeObserver
|
|
|
|
// Mock URL.createObjectURL
|
|
URL.createObjectURL = vi.fn(() => 'mock-url')
|
|
URL.revokeObjectURL = vi.fn()
|
|
|
|
// Mock scrollTo
|
|
window.scrollTo = vi.fn()
|
|
|
|
// 清理 localStorage
|
|
afterEach(() => {
|
|
localStorage.clear()
|
|
sessionStorage.clear()
|
|
})
|