XiTest 技术架构 v1.0 · 全自动测试验证平台
文档定位
- 产品定位:Xisound L2 层"羲音测试台"——算法链路集成测试 + 功能回归 + 模块单测 + UI 回归
- 形态:独立 web app · 可 deep-link 从 XiStudio 呼起
- 上游:D0 产品矩阵 V1.1 · D3-FE-ARCH-001 顶层架构 · D3-FE-ARCH-005 路由与 Deep-link
- 下游:D3-FE-PLAN-006 XiTest v0.5 实现 plan
1. 产品定位与目标
1.1 产品定位
XiTest = 羲音测试台(Y1Q2 v0.5 · Y1Q4 v1.0 GA)。为 Xisound 生态提供全自动测试验证平台,承担算法回归、模块单测、调音对比、UI 视觉回归四大测试场景。
1.2 核心能力
- Test Suite Manager:测试套件组织 · 用例版本化 · 分类打标签
- Module Unit Test:模块级单测(inject-signal → capture → assert)· 继承现有 MC
module_test能力 - Link Integration Test:整链路集成测试 · 多源多汇场景
- Tuning Regression:调音方案 vs baseline 对比 · 频响差异 / 感知差异
- UI Regression(可选):视觉回归(Playwright 截屏 diff)
- Report Dashboard:测试报告列表 · 历史趋势 · 失败根因分析
1.3 目标用户
| 用户类型 | 核心场景 | XiTest 提供的能力 |
|---|---|---|
| QA 工程师 | 版本回归 | 全量套件自动跑 + HTML 报告导出 |
| 算法工程师 | 调试新模块 | inject-signal 单测 + 对比基线 |
| 调音师 | 调音方案验证 | Tuning Regression + A/B 对比 |
| 集成工程师 | 交付前验收 | 全链路端到端测试 + 车型多场景组合 |
1.4 版本矩阵
| 版本 | 时点 | 覆盖能力 |
|---|---|---|
| v0.5 灯塔 | Y1Q2 | 迁移现有 3 种 appMode(module_test / test_runner / tuning_test)+ 基础 Report |
| v1.0 GA | Y1Q4 | 完整 5 大模块 · 集成测试 + 调音回归 · 首次服务灯塔 OEM 量产验收 |
| v2.0 | Y2Q4 | UI 回归 + AI 失败根因分析(XiMind 驱动)+ 跨车型矩阵测试 |
1.5 与现有 3 个 appMode 的关系
现有 frontend_vue3/ 有 3 个 test 相关 appMode(调研于 2026-05-08):
module_test→ Module Unit Test 模块test_runner→ Test Suite Manager + Runtuning_test→ Tuning Regression
XiTest v0.5 完整迁移这 3 个能力到独立 app(/xi-test/),废弃 appMode。
2. 架构总览
2.1 XiTest 在 Monorepo 中的位置
graph TB
subgraph App["apps/xi-test(独立 app)"]
Router["vue-router"]
Shell["TestLayout"]
subgraph Modules["5 大功能模块"]
SuiteMgr["Test Suite Manager"]
ModuleUT["Module Unit Test"]
IntegTest["Link Integration Test"]
TuneReg["Tuning Regression"]
ReportDash["Report Dashboard"]
end
end
subgraph Packages["packages/"]
UIKit["@xi/ui-kit"]
Protocol["@xi/protocol"]
StoreCore["@xi/store-core"]
DSPUtils["@xi/dsp-utils"]
AISDK["@xi/ai-sdk (Y2)"]
end
subgraph Backend["Backend"]
TestRunner["Test Runner Service<br/>(C# 后端 / pysidecar 分析)"]
Baseline["Baseline Storage<br/>(S3/OSS)"]
end
subgraph Entry["启动入口"]
Direct["独立启动<br/>test.xisound.com"]
FromStudio["XiStudio deep-link<br/>xi://xi-test/run/:id"]
end
Entry --> Router --> Shell --> Modules
ModuleUT --> TestRunner
IntegTest --> TestRunner
TuneReg --> Baseline
TuneReg --> DSPUtils
Modules --> UIKit
Modules --> Protocol
Modules --> StoreCore
classDef app fill:#FFF4E6,stroke:#D4A574,stroke-width:3px
classDef module fill:#FFFFFF,stroke:#6B7280,stroke-width:1px
classDef pkg fill:#F5F2EA,stroke:#6B7280,stroke-width:1px
classDef be fill:#F0E6FA,stroke:#9D4EDD,stroke-width:2px
classDef entry fill:#E6F7FF,stroke:#1890FF,stroke-width:2px
class App,Router,Shell app
class SuiteMgr,ModuleUT,IntegTest,TuneReg,ReportDash module
class UIKit,Protocol,StoreCore,DSPUtils,AISDK pkg
class TestRunner,Baseline be
class Direct,FromStudio entry
class App,Modules xySgL2; class Packages,Entry xySgL4; class Backend xySgL3;
2.2 技术栈
| 层 | 选型 | 来源 |
|---|---|---|
| 框架 | Vue 3.4+ | D3-FE-ARCH-001 §7.1 |
| 路由 | vue-router 4 | 同上 |
| 状态 | Pinia 2+ | 同上 |
| UI | @xi/ui-kit(含 <SpectrumChart> <WaveformChart> <EQCurveEditor>) |
D3-FE-ARCH-003 |
| DSP | @xi/dsp-utils(FFT / RMS / LUFS 计算用于 assert) | 同上 |
| 测试执行 | 后端 Test Runner Service(C#)+ pysidecar(Python 分析) | 后端 |
| 视觉回归 | @playwright/test(仅 v2.0+) | 新增 |
| 报告导出 | jsPDF + html2canvas | 新增 |
3. 目录结构
apps/xi-test/
├── src/
│ ├── main.ts
│ ├── App.vue
│ ├── router/
│ │ ├── index.ts # /suites, /run/:id, /reports, /module-test, /tuning-regression, /intent/:name
│ │ └── guards.ts
│ ├── layouts/
│ │ └── TestLayout.vue
│ ├── views/
│ │ ├── TestSuiteListView.vue
│ │ ├── TestSuiteDetailView.vue
│ │ ├── TestRunView.vue # 运行态
│ │ ├── ReportsView.vue
│ │ ├── ReportDetailView.vue
│ │ ├── ModuleUnitTestView.vue # 继承 module_test
│ │ ├── TuningRegressionView.vue # 继承 tuning_test
│ │ └── IntentHandlerView.vue
│ ├── components/
│ │ ├── suite/
│ │ │ ├── SuiteCard.vue
│ │ │ ├── TestCaseEditor.vue # 编辑用例
│ │ │ └── AssertionBuilder.vue # 组装断言
│ │ ├── runner/
│ │ │ ├── RunControl.vue # 开始/停止/暂停
│ │ │ ├── RunProgress.vue # 进度条
│ │ │ ├── RunLog.vue # 实时日志
│ │ │ └── CaseStatusList.vue # 用例列表状态
│ │ ├── module-test/
│ │ │ ├── SignalInjector.vue # 注入信号配置
│ │ │ ├── CaptureViewer.vue # 采集结果
│ │ │ └── AssertionResult.vue # 断言结果
│ │ ├── regression/
│ │ │ ├── BaselineSelector.vue # 选择 baseline
│ │ │ ├── DiffVisualizer.vue # 频响差异可视化
│ │ │ └── PerceptualDiff.vue # 感知差异
│ │ └── report/
│ │ ├── ReportList.vue
│ │ ├── ReportSummary.vue
│ │ ├── TrendChart.vue # 历史通过率趋势
│ │ └── FailureAnalysis.vue # 失败根因分析
│ ├── stores/
│ │ ├── useTestSuiteStore.ts
│ │ ├── useTestRunStore.ts
│ │ ├── useModuleTestStore.ts
│ │ ├── useTuningRegressionStore.ts
│ │ └── useReportStore.ts
│ ├── services/
│ │ ├── testRunnerApi.ts # 后端 Test Runner 通信
│ │ ├── baselineApi.ts # Baseline 管理
│ │ └── pdfExport.ts
│ └── types/
│ ├── TestSuite.ts
│ ├── TestCase.ts
│ ├── Assertion.ts
│ ├── TestReport.ts
│ └── Baseline.ts
├── tests/
│ ├── unit/
│ └── e2e/
├── vite.config.ts
├── tsconfig.json
├── package.json
└── README.md
4. 核心模块详细设计
4.1 Test Suite Manager
职责:管理测试套件、用例、断言。
数据模型:
// types/TestSuite.ts
export interface TestSuite {
id: string
name: string
description: string
tags: string[]
cases: TestCase[]
createdAt: number
updatedAt: number
version: string
}
export interface TestCase {
id: string
name: string
type: 'module-unit' | 'link-integration' | 'tuning-regression' | 'ui-regression'
moduleRef?: string // 针对的模块(module-unit)
linkRef?: string // 针对的链路(link-integration)
baselineId?: string // tuning-regression 的基线
inputs: SignalInput[]
assertions: Assertion[]
timeout: number // 秒
retryOnFailure?: number
}
export interface Assertion {
id: string
type: 'rms-range' | 'peak-max' | 'thd-max' | 'snr-min' | 'frequency-response' | 'custom-script'
target: string // 目标端口/信号
expected: any
tolerance?: number
}
4.2 Module Unit Test(继承 module_test)
职责:对单个模块做 inject-signal → capture → assert 流程。
从现有 MC 迁移的能力:
现有 module_test 能力 |
目标位置 |
|---|---|
| 选择模块 + 配置参数 | ModuleUnitTestView 顶部表单 |
| 注入 tone/noise/sweep | SignalInjector.vue |
| 采集输出 | CaptureViewer.vue · 复用 @xi/ui-kit <WaveformChart> / <SpectrumChart> |
| 断言(RMS/峰值等) | AssertionResult.vue + @xi/dsp-utils |
数据流:
sequenceDiagram
participant UI as ModuleUnitTestView
participant Store as useModuleTestStore
participant API as testRunnerApi
participant BE as Backend (Test Runner)
participant DSP as DSP Module
UI->>Store: 配置用例(module + inputs + assertions)
UI->>Store: runCase()
Store->>API: POST /api/test/run-module-case
API->>BE: 调用 Test Runner
BE->>DSP: 加载模块 + 注入信号
DSP-->>BE: 输出采集数据
BE->>BE: 计算断言(RMS/FFT/THD...)
BE-->>API: TestCaseResult{pass/fail, metrics, wavFilePath}
API-->>Store: 结果
Store-->>UI: 渲染 AssertionResult + 图表
4.3 Link Integration Test
职责:整链路端到端测试。用户定义链路配置 → 运行 → 采集 sink 输出 → 断言。
场景示例:
| 场景 | inputs | assertions |
|---|---|---|
| 基础直通 | 1kHz tone @ source_1 | sink_1 RMS ∈ [-12, -6] dBFS |
| 多源混音 | tone@s1 + pink_noise@s2 → mixer | sink_1 FFT 有 1kHz 峰 + 其他频段在粉噪包络内 |
| EQ 效果 | sweep @ source_1 → EQ → sink_1 | 频响符合 EQ 参数预期(tolerance ±1dB) |
| 动态范围 | 0dBFS pulse → limiter → sink_1 | peak ≤ -3dBFS |
4.4 Tuning Regression(继承 tuning_test)
职责:当前调音方案 vs baseline 的对比分析。
核心能力:
- Baseline 管理:存储某车型/某时间点的"金标准"调音方案 + 测量数据
- 频响差异可视化:当前 vs baseline 的频响曲线叠加 + 差异填充
- 感知差异分析:用心理声学指标(ITU-R BS.1387 PEAQ / LUFS / Loudness Range)量化差异
- 容忍度配置:用户定义可接受偏差(如 ±2dB @ 100-1000Hz)
数据模型:
export interface Baseline {
id: string
name: string
vehicleModel: string
capturedAt: number
measurements: {
position: string
frequencyResponse: { freqs: number[]; magnitudeDb: number[] }
thd: number
snr: number
lufs: number
}[]
tuningState: TunerState // EQ/Dyn/Delay 参数快照
}
export interface RegressionReport {
baselineId: string
currentSnapshotId: string
diffs: {
position: string
magnitudeDiff: { freqs: number[]; diffDb: number[] } // 逐频率点差值
maxDeviation: { freq: number; deviationDb: number }
perceptualScore: number // PEAQ 或类似指标
withinTolerance: boolean
}[]
overallPass: boolean
}
4.5 Report Dashboard
职责:测试报告管理 + 历史趋势 + 失败分析。
关键视图:
- ReportsView:列表视图 · 按日期/套件/状态筛选
- ReportDetailView:单次运行详情 · 每用例状态 · 失败的 assertion 详细
- TrendChart:近 N 次运行的通过率/耗时趋势
- FailureAnalysis(v2.0 · XiMind 驱动):根据日志模式识别失败根因(配置错误 / 环境问题 / 真实 regression)
5. 路由设计
(完整路由定义见 D3-FE-ARCH-005 §3.3)
5.1 Intent 清单
| Intent | 触发场景 | 必需参数 |
|---|---|---|
run-suite |
XiStudio 点"运行测试" | suiteId + autoStart=true |
regression |
对比当前工程 vs baseline | projectId + baselineId |
inject-signal |
快速模块单测 | moduleId + signalType |
6. Store 设计
6.1 useTestSuiteStore
export const useTestSuiteStore = defineStore('xi-test-suite', () => {
const suites = ref<TestSuite[]>([])
const activeSuite = ref<TestSuite | null>(null)
async function list(): Promise<TestSuite[]>
async function create(name: string): Promise<TestSuite>
async function open(id: string): Promise<void>
async function addCase(caseData: TestCase): Promise<void>
async function removeCase(caseId: string): Promise<void>
async function save(): Promise<void>
return { suites, activeSuite, list, create, open, addCase, ... }
})
6.2 useTestRunStore
export const useTestRunStore = defineStore('xi-test-run', () => {
const currentRun = ref<TestRun | null>(null)
const progress = ref(0)
const caseResults = ref<Map<string, CaseResult>>(new Map())
const isRunning = ref(false)
async function startRun(suiteId: string, options?: RunOptions): Promise<void>
async function stopRun(): Promise<void>
async function pauseRun(): Promise<void>
async function resumeRun(): Promise<void>
function subscribeRunEvents(): void // WS 订阅实时进度
return { currentRun, progress, caseResults, isRunning, startRun, ... }
})
7. 与后端的接口契约
7.1 HTTP API
| 端点 | 方法 | 用途 |
|---|---|---|
/api/test/suites |
GET/POST | 套件 CRUD |
/api/test/suites/:id |
GET/PUT/DELETE | 单套件 |
/api/test/run |
POST | 启动运行 · body: |
/api/test/run/:runId |
GET | 查询运行态 |
/api/test/run/:runId/stop |
POST | 停止 |
/api/test/reports |
GET | 报告列表 |
/api/test/reports/:id |
GET | 报告详情 |
/api/test/baselines |
GET/POST | baseline 管理 |
/api/test/regression |
POST | 触发回归对比 |
7.2 WebSocket
- 订阅
test-run-event(新增 schema ·@xi/protocol):run-started/case-started/case-completed/run-completed- 实时日志流
8. 测试策略
8.1 自测(XiTest 自己也要测)
- Store CRUD 单测
- 各 View 组件浅渲染测试
- Mock 后端响应做 e2e
8.2 性能基线
- 10 用例套件运行:< 30s 完成(不含 DSP 实际处理时间)
- 报告列表(100 条):< 1s 渲染
- TrendChart 100 天数据:60 FPS
9. DQ 与风险
9.1 新增 DQ
| DQ 编号 | 问题 | 建议 |
|---|---|---|
| DQ-TEST-01 | 测试用例的 YAML/JSON 互转 | v1.0 仅 JSON · v2.0 支持 YAML 导入(便于 PR review) |
| DQ-TEST-02 | 大量 wav 附件存储策略 | 存 S3/OSS · 报告只存引用 + 缩略图 |
| DQ-TEST-03 | 跨 Agent 失败根因分析 | v2.0 XiMind 驱动 · 需大量历史数据标注 |
| DQ-TEST-04 | UI 回归的截图 baseline 管理 | v2.0 · 用 Chromatic 或自建 |
9.2 风险
| 风险 | 缓解 |
|---|---|
| 后端 Test Runner 性能瓶颈(并发跑多套件) | 后端用任务队列 + 限流 · UI 显示排队状态 |
| Baseline 漂移(环境/硬件变了误报 regression) | 记录运行环境指纹 · UI 提示可能的环境因素 |
| 断言配置复杂度高(非测试工程师难上手) | 提供 assertion 模板库 + AI 辅助生成(v2.0) |
10. 版本与变更记录
| 版本 | 日期 | 作者 | 说明 |
|---|---|---|---|
| v1.0 | 2026-05-08 | work-cline | 初稿 · 5 大模块 · 继承 3 appMode · 路由 + Intent · 与后端契约 |