Files
video_socket-server/.qoder/repowiki/zh/content/测试框架.md
2026-05-16 13:24:02 +08:00

20 KiB
Raw Blame History

测试框架

**本文引用的文件** - [jest.config.js](file://jest.config.js) - [jest.config.js](file://client/jest.config.js) - [jest.setup.js](file://client/jest.setup.js) - [package.json](file://package.json) - [package.json](file://client/package.json) - [httphandler.test.ts](file://test/httphandler.test.ts) - [websockethandler.test.ts](file://test/websockethandler.test.ts) - [signaling.test.js](file://client/test/signaling.test.js) - [mocksignaling.js](file://client/test/mocksignaling.js) - [peerconnection.test.js](file://client/test/peerconnection.test.js) - [peerconnectionmock.js](file://client/test/peerconnectionmock.js) - [resizeobservermock.js](file://client/test/resizeobservermock.js) - [testutils.js](file://client/test/testutils.js) - [sender.test.js](file://client/test/sender.test.js) - [httphandler.ts](file://src/class/httphandler.ts)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本指南面向视频流服务器项目的测试体系,系统性阐述测试策略与架构,覆盖单元测试、集成测试与端到端测试的组织方式;详解 Jest 测试框架在服务端与客户端的配置与使用,包括测试环境设置、模拟对象与工具库;提供 WebRTC 信令与数据通道输入远程控制等关键功能的测试示例;说明测试覆盖率要求与报告生成;总结测试最佳实践与调试技巧,并给出测试用例编写指南。

项目结构

项目采用分层与按功能划分的组织方式:

  • 服务端src核心业务逻辑与 HTTP/WebSocket 信令处理
  • 服务端测试test基于 Express 模拟与 WebSocket 模拟器的集成测试
  • 客户端client前端 JS 模块与 WebRTC 交互逻辑
  • 客户端测试client/testJSDOM 环境下的单元与集成测试,含 WebRTC 模拟与信令模拟
graph TB
subgraph "服务端"
S1["HTTP处理器<br/>src/class/httphandler.ts"]
S2["WebSocket处理器<br/>src/class/websockethandler.ts"]
end
subgraph "服务端测试"
T1["HTTP信令测试<br/>test/httphandler.test.ts"]
T2["WebSocket信令测试<br/>test/websockethandler.test.ts"]
end
subgraph "客户端"
C1["信令模块<br/>client/src/signaling.js"]
C2["WebRTC封装<br/>client/src/peer.js"]
C3["输入远程控制<br/>client/src/inputremoting.js"]
end
subgraph "客户端测试"
CT1["信令测试<br/>client/test/signaling.test.js"]
CT2["Peer连接测试<br/>client/test/peerconnection.test.js"]
CT3["发送器测试<br/>client/test/sender.test.js"]
CM1["信令模拟<br/>client/test/mocksignaling.js"]
CM2["Peer模拟<br/>client/test/peerconnectionmock.js"]
CU1["测试工具<br/>client/test/testutils.js"]
end
T1 --> S1
T2 --> S2
CT1 --> C1
CT2 --> C2
CT3 --> C3
CT1 --> CM1
CT2 --> CM2
CT2 --> CU1

图表来源

章节来源

核心组件

  • 测试运行器与配置
    • 服务端 Jest 配置启用 TypeScript 转换、Node 环境、覆盖率收集与默认匹配规则
    • 客户端 Jest 配置启用 JSDOM 环境、setupFilesAfterEnv 引入全局模拟与 WebRTC 模拟
  • 测试工具与模拟
    • 服务端Express 模拟中间件与 WebSocket 模拟器,验证 HTTP/WebSocket 信令流程
    • 客户端JSDOM 环境下注入 fetch、TextEncoder/Decoder、RTCPeerConnection 及 ResizeObserver 的模拟实现
    • 信令模拟MockSignaling 与 MockPublic/PrivateSignalingManager支持公共/私有模式下的信令广播与连接管理
    • WebRTC 模拟PeerConnectionMock、SessionDescriptionMock、IceCandidateMock覆盖 SDP 描述、ICE 候选、事件触发与状态机
    • 工具库waitFor、sleep、getRTCConfiguration 等,支撑异步等待与测试配置
  • 关键模块测试
    • HTTP 信令会话创建、连接创建、offer/answer/candidate 收发、断开清理与超时回收
    • WebSocket 信令:连接建立、消息转发、断开通知与多客户端广播
    • 信令集成:公共/私有模式下跨客户端的信令收发与连接极性判定
    • WebRTC PeeraddTrack/addTransceiver/createDataChannel、协商事件、候选收集、错误状态抛出
    • 输入远程控制:鼠标/键盘/触摸事件捕获与 RTC 数据通道发送

章节来源

架构总览

测试架构分为三层:

  • 单元测试层:针对纯函数与小模块(如工具函数、模型类),快速验证边界条件与异常分支
  • 集成测试层组合模块与外部依赖Express 中间件、WebSocket 服务器),验证端到端流程
  • 端到端测试层:启动真实服务进程,进行跨浏览器/设备的信令与媒体交互验证
sequenceDiagram
participant Test as "测试用例"
participant HTTP as "HTTP处理器<br/>httphandler.ts"
participant WS as "WebSocket处理器<br/>websockethandler.ts"
participant MockSig as "信令模拟<br/>mocksignaling.js"
participant Peer as "Peer连接模拟<br/>peerconnectionmock.js"
Test->>HTTP : "创建会话/连接"
HTTP-->>Test : "返回JSON响应"
Test->>MockSig : "创建连接/发送offer/answer/candidate"
MockSig-->>Test : "触发connect/offer/answer/candidate事件"
Test->>Peer : "onGotDescription/onGotCandidate"
Peer-->>Test : "触发sendoffer/sendanswer/sendcandidate事件"
Test->>WS : "WebSocket信令收发"
WS-->>Test : "消息转发/断开通知"

图表来源

详细组件分析

服务端 HTTP 信令测试(单元/集成)

  • 测试目标
    • 会话生命周期:创建、检查、删除
    • 连接生命周期:创建、断开、清理
    • 信令消息offer/answer/candidate 的收发与查询
    • 模式差异:公共/私有模式下的连接极性与广播行为
    • 超时机制:长时间无请求的会话清理
  • 关键断言
    • 响应状态码与 JSON 结构
    • 会话内连接列表与消息队列
    • 私有模式下仅配对连接可互相接收信令
  • 异步与超时
    • 使用定时器与延迟模拟,验证超时清理逻辑
flowchart TD
Start(["开始"]) --> CreateSession["创建会话"]
CreateSession --> CreateConn["创建连接"]
CreateConn --> SendOffer["发送Offer"]
SendOffer --> ReceiveOffer["接收Offer"]
ReceiveOffer --> SendAnswer["发送Answer"]
SendAnswer --> ReceiveAnswer["接收Answer"]
ReceiveAnswer --> SendCandidate["发送Candidate"]
SendCandidate --> ReceiveCandidate["接收Candidate"]
ReceiveCandidate --> DeleteConn["删除连接"]
DeleteConn --> Cleanup["清理会话/断开通知"]
Cleanup --> End(["结束"])

图表来源

章节来源

服务端 WebSocket 信令测试(集成)

  • 测试目标
    • 多客户端连接与消息广播
    • 私有模式下仅配对连接可互相接收信令
    • 断开连接时双向通知
  • 关键断言
    • WebSocket 消息协议字段from/to/type/data
    • 消息到达顺序与数量
sequenceDiagram
participant C1 as "客户端1"
participant C2 as "客户端2"
participant WS as "WebSocket服务器"
C1->>WS : "connect(connectionId)"
WS-->>C1 : "connect(own)"
WS-->>C2 : "connect(other)"
C1->>WS : "offer({connectionId,sdp})"
WS-->>C2 : "offer({from,to,type,data})"
C2->>WS : "answer({connectionId,sdp})"
WS-->>C1 : "answer({from,to,type,data})"
C1->>WS : "disconnect(connectionId)"
WS-->>C1 : "disconnect"
WS-->>C2 : "disconnect"

图表来源

章节来源

客户端信令测试(集成/端到端)

  • 测试目标
    • 公共/私有模式下信令收发与连接极性
    • HTTP 与 WebSocket 两种信令通道
    • 本地 MockSignaling 与真实服务进程的对比
  • 关键断言
    • connect/offer/answer/candidate 事件的 detail 字段
    • 断开事件触发次数与 connectionId 匹配
  • 端到端验证
    • 通过 jest-dev-server 启动服务进程,使用真实 Signaling/WebSocketSignaling 进行连通性测试
sequenceDiagram
participant T as "测试用例"
participant M as "MockSignaling"
participant S as "Signaling(HTTP)"
participant W as "WebSocketSignaling"
participant P as "服务进程"
T->>M : "start/createConnection/sendOffer"
M-->>T : "dispatchEvent(connect/offer/answer/candidate)"
T->>S : "start/createConnection/sendOffer"
S->>P : "HTTP请求"
P-->>S : "响应/消息存储"
T->>W : "start/createConnection/sendOffer"
W->>P : "WebSocket消息"
P-->>W : "消息转发"

图表来源

章节来源

WebRTC Peer 连接测试(单元/集成)

  • 测试目标
    • 构造函数初始化与事件监听器绑定
    • addTrack/addTransceiver/createDataChannel 触发协商
    • onGotDescription/onGotCandidate 的事件与状态变化
    • 候选收集与错误状态抛出
  • 关键断言
    • 发送 offer/answer/candidate 的事件详情
    • negotiated 事件触发时机
    • 候选未被接受的边界条件
classDiagram
class Peer {
+connectionId
+pc
+addEventListener(event, handler)
+close()
+addTrack(connectionId, track)
+addTransceiver(connectionId, kind)
+createDataChannel(connectionId, label)
+onGotDescription(connectionId, desc)
+onGotCandidate(connectionId, candidate)
}
class PeerConnectionMock {
+localDescription
+remoteDescription
+addTrack(track)
+addTransceiver(kind)
+createDataChannel(label)
+setLocalDescription(desc)
+setRemoteDescription(desc)
+addIceCandidate(candidate)
+close()
}
Peer --> PeerConnectionMock : "使用"

图表来源

章节来源

输入远程控制测试(单元)

  • 测试目标
    • 设备注册与事件订阅
    • 鼠标/键盘/触摸事件序列化与发送
    • RTC 数据通道状态与发送调用
  • 关键断言
    • 设备数量与事件回调注册
    • 数据通道 send 调用次数与 ArrayBuffer 内容

章节来源

依赖分析

  • 测试运行与环境
    • 服务端Jest + ts-jest + @jest-mock/express + jest-websocket-mock
    • 客户端Jest + jest-environment-jsdom + jest-dev-server + node-fetch
  • 模拟与工具
    • WebRTC 模拟RTCPeerConnection、SessionDescription、IceCandidate
    • DOM/ResizeObserver 模拟JSDOM 环境缺失时的 polyfill
    • 信令模拟MockSignaling 与管理器
    • 工具函数:等待、睡眠、唯一 ID、RTC 配置
graph LR
Jest["Jest"] --> TS["ts-jest"]
Jest --> JSDOM["jest-environment-jsdom"]
Jest --> DevServer["jest-dev-server"]
Jest --> WS["jest-websocket-mock"]
Client["客户端测试"] --> JSDOM
Client --> DevServer
Client --> Fetch["node-fetch"]
Server["服务端测试"] --> ExpressMock["@jest-mock/express"]
Server --> WS

图表来源

章节来源

性能考虑

  • 测试并发与超时
    • 客户端测试配置了较短的 testTimeout避免长耗时阻塞
    • 使用延迟与等待函数替代硬编码 sleep提升稳定性
  • 覆盖率与报告
    • 启用 v8 覆盖收集与输出目录,建议结合 CI 生成 LCOV 报告
    • 对关键路径HTTP/WebSocket 信令、WebRTC 状态机)优先保证高覆盖率
  • 端到端成本
    • 真实服务进程启动与关闭需注意资源释放Linux 平台增加等待时间

章节来源

故障排查指南

  • 环境变量与脚本
    • 服务端脚本使用 Jest 直接执行 test/*.ts确保 ts-jest 与 TypeScript 配置正确
    • 客户端脚本使用 Node VM 模块运行 Jest确保 package.json 中的脚本与依赖一致
  • JSDOM 缺失 API
    • 在 jest.setup.js 中注入 fetch、TextEncoder/Decoder、RTCPeerConnection、ResizeObserver
    • 若仍报错,确认 jest-environment-jsdom 版本与 jest.setup.js 的引入顺序
  • WebRTC 模拟问题
    • 确认 PeerConnectionMock 的事件回调与状态机逻辑与实际浏览器行为一致
    • 对于 InvalidStateError 等异常,需在测试中显式断言
  • 信令模拟一致性
    • MockSignaling 与真实服务端的字段保持一致connectionId、sdp、polite、candidate 等)
    • 私有模式下仅配对连接可互相接收信令,否则应断言未收到
  • 端到端启动失败
    • 检查 jest-dev-server 的命令拼接与端口占用
    • Linux 平台在 teardown 后增加等待时间,避免进程残留导致后续测试失败

章节来源

结论

本项目采用“单元测试 + 集成测试 + 端到端测试”的分层策略,结合 Jest 与多种模拟技术,实现了对 HTTP/WebSocket 信令、WebRTC 连接与输入远程控制的全面覆盖。通过 MockSignaling、PeerConnectionMock 与工具库,测试在可控环境中复现复杂交互;通过公共/私有模式与超时清理逻辑的验证,确保系统在真实场景下的健壮性。

附录

测试策略与组织

  • 单元测试
    • 针对纯函数与小模块,断言边界与异常
    • 示例:工具函数、模型类、状态转换
  • 集成测试
    • 组合模块与外部依赖,验证流程完整性
    • 示例HTTP 信令、WebSocket 信令、WebRTC 状态机
  • 端到端测试
    • 启动真实服务进程,验证跨客户端交互
    • 示例HTTP/WebSocket 信令通道、真实浏览器环境

章节来源

Jest 配置与使用要点

  • 服务端
    • 启用 ts-jest 转换Node 环境,收集覆盖率,匹配 test/*.ts
  • 客户端
    • JSDOM 环境setupFilesAfterEnv 引入全局模拟,匹配 client/test/**/*.test.js
  • 脚本
    • 服务端npm/yarn test 指向 Jest 并传入测试文件
    • 客户端:使用 Node VM 模块运行 Jest

章节来源

覆盖率要求与报告

  • 覆盖率收集
    • 开启 collectCoverage输出目录为 coverage提供 v8 覆盖器
  • 报告生成
    • 建议在 CI 中生成 LCOV 报告并与平台集成
  • 要求建议
    • 关键模块HTTP/WebSocket 信令、WebRTC 状态机)覆盖率不低于 80%
    • 重要分支与异常路径必须覆盖

章节来源

WebRTC 功能测试示例

  • 信令处理测试
    • 使用 MockSignaling 验证公共/私有模式下的 offer/answer/candidate 分发
    • 使用 jest-websocket-mock 验证 WebSocket 信令通道
  • Peer 连接测试
    • 使用 PeerConnectionMock 验证 addTrack/addTransceiver/createDataChannel 的事件触发
    • 验证 onGotDescription/onGotCandidate 的状态变化与候选收集

章节来源

客户端测试与服务器端测试示例

  • 客户端
    • 信令:公共/私有模式、HTTP/WebSocket 三种通道
    • WebRTC构造、关闭、事件触发、候选收集
    • 输入远程控制:事件捕获与发送
  • 服务器端
    • HTTP 信令:会话/连接生命周期、消息收发、超时清理
    • WebSocket 信令:多客户端广播、断开通知

章节来源

测试最佳实践与调试技巧

  • 最佳实践
    • 使用 describe/it 分层组织测试,命名清晰表达意图
    • 使用 beforeEach/beforeAll 准备测试上下文,避免重复代码
    • 对异步流程使用 waitFor/sleep 替代固定延时
    • 对模拟对象进行 spy/restore避免副作用影响其他测试
  • 调试技巧
    • 在 jest.setup.js 注入必要 polyfill减少环境差异
    • 使用 console.log 或断点定位事件触发时机
    • 对 WebSocket 与 HTTP 信令分别断言消息字段与数量

章节来源