版本:1.0
日期:2026年1月15日
状态:草案
本文档定义 TianShanOS 的测试策略、测试范围和测试用例。测试分为以下几个层次:
| 测试层次 | 描述 | 运行环境 |
|---|---|---|
| 单元测试 | 单个模块/函数的独立测试 | 主机 (Unity + CMock) |
| 集成测试 | 多模块协作测试 | 目标硬件 (ESP32S3) |
| 系统测试 | 完整系统功能验证 | 目标硬件 + 外设 |
| 压力测试 | 长时间运行/高负载测试 | 目标硬件 |
| 安全测试 | 认证/加密/权限测试 | 目标硬件 |
| 项目 | 规格 |
|---|---|
| 主控芯片 | ESP32S3 (N16R8) |
| 开发板 | RM01 自定义载板 |
| LED 灯带 | WS2812B (触摸1颗, 板载28颗, 矩阵32x32=1024颗) |
| SD 卡 | 16GB FAT32 |
| 网络 | W5500 以太网 + WiFi |
| 电源监控 | ADC电压监控 (GPIO18, 11.4:1) + PZEM功率表 (GPIO47, 9600baud) |
| 风扇 | PWM 4线风扇 x 2 (25kHz, 10-bit) |
| 项目 | 版本 |
|---|---|
| ESP-IDF | v5.5.1 |
| Unity | ESP-IDF 内置 |
| Python | 3.9+ (测试脚本) |
| pytest | 最新版 (集成测试) |
- 串口监控:
idf.py monitor - HTTP 测试: curl / Postman / pytest-httpx
- WebSocket 测试: wscat / Python websockets
- 网络分析: Wireshark
- 内存分析: ESP-IDF heap trace
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| CFG-001 | 默认值读取 | 未设置的配置返回默认值 | P0 |
| CFG-002 | NVS 读写 | 配置正确存储和读取 | P0 |
| CFG-003 | 文件后端读写 | JSON 配置正确解析 | P0 |
| CFG-004 | 变更通知 | 回调在配置变更时触发 | P1 |
| CFG-005 | 配置验证 | 无效值被拒绝 | P1 |
| CFG-006 | 并发访问 | 多任务读写无数据竞争 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| EVT-001 | 事件发布 | 订阅者收到事件 | P0 |
| EVT-002 | 多订阅者 | 所有订阅者都收到事件 | P0 |
| EVT-003 | 事件过滤 | 只收到订阅的事件类型 | P0 |
| EVT-004 | 优先级顺序 | 高优先级先处理 | P1 |
| EVT-005 | 事务支持 | 事务内事件可回滚 | P2 |
| EVT-006 | 队列满处理 | 返回错误而非崩溃 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| SVC-001 | 服务注册 | 服务成功注册 | P0 |
| SVC-002 | 依赖解析 | 依赖服务先启动 | P0 |
| SVC-003 | 阶段启动 | 按阶段顺序启动 | P0 |
| SVC-004 | 循环依赖 | 检测并报错 | P1 |
| SVC-005 | 健康检查 | 异常服务被检测 | P1 |
| SVC-006 | 服务停止 | 按逆序停止 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| LOG-001 | 日志级别过滤 | 低于当前级别的日志不输出 | P0 |
| LOG-002 | 多输出目标 | 同时输出到串口和文件 | P1 |
| LOG-003 | 格式化 | 时间戳和模块名正确 | P1 |
| LOG-004 | 缓冲区管理 | 循环缓冲区正确工作 | P2 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| GPIO-001 | 输出控制 | 电平正确设置 | P0 |
| GPIO-002 | 输入读取 | 正确读取外部电平 | P0 |
| GPIO-003 | 中断触发 | 边沿触发中断 | P0 |
| GPIO-004 | 上下拉配置 | 内部电阻正确工作 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| PWM-001 | 占空比设置 | 输出波形正确 | P0 |
| PWM-002 | 频率设置 | 频率在允许范围 | P0 |
| PWM-003 | 渐变效果 | 平滑过渡 | P1 |
| PWM-004 | 多通道 | 独立控制 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| I2C-001 | 设备扫描 | 检测到连接的设备 | P0 |
| I2C-002 | 读写操作 | 数据正确传输 | P0 |
| I2C-003 | NAK 处理 | 超时不崩溃 | P1 |
| I2C-004 | 多设备 | 地址正确寻址 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| SPI-001 | 数据传输 | 数据正确收发 | P0 |
| SPI-002 | DMA 模式 | 大数据块传输 | P1 |
| SPI-003 | 多设备 | CS 正确控制 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| UART-001 | 数据收发 | 数据正确传输 | P0 |
| UART-002 | 波特率 | 常用波特率工作 | P0 |
| UART-003 | 行读取 | 正确识别行结束 | P1 |
| UART-004 | 缓冲区溢出 | 不丢失数据或崩溃 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| ADC-001 | 电压读取 | 读数在合理范围 | P0 |
| ADC-002 | 校准 | 读数准确度 ±5% | P1 |
| ADC-003 | 多通道 | 通道切换正确 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| LED-001 | 单像素设置 | 颜色正确显示 | P0 |
| LED-002 | 填充 | 整条填充颜色 | P0 |
| LED-003 | 亮度控制 | 亮度变化明显 | P0 |
| LED-004 | 图层混合 | 多图层正确叠加 | P1 |
| LED-005 | 特效播放 | 动画流畅 | P1 |
| LED-006 | 图像显示 | BMP/PNG/JPG 正确渲染 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| STG-001 | SPIFFS 挂载 | 成功挂载 | P0 |
| STG-002 | SD 卡挂载 | FAT32 正确识别 | P0 |
| STG-003 | 文件读写 | 内容正确 | P0 |
| STG-004 | 目录操作 | 创建/删除/遍历 | P1 |
| STG-005 | 大文件 | 处理 > 1MB 文件 | P2 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| CON-001 | 命令执行 | 内置命令工作 | P0 |
| CON-002 | 参数解析 | 正确解析参数 | P0 |
| CON-003 | 帮助系统 | 显示帮助信息 | P0 |
| CON-004 | 历史记录 | 上下键导航 | P1 |
| CON-005 | 多语言 | 语言切换工作 | P1 |
| CON-006 | 脚本执行 | run 命令工作 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| SEC-001 | 会话创建 | 成功创建会话 | P0 |
| SEC-002 | Token 验证 | 有效 Token 通过 | P0 |
| SEC-003 | 权限检查 | 权限不足被拒绝 | P0 |
| SEC-004 | SHA 哈希 | 输出正确 | P0 |
| SEC-005 | AES-GCM | 加解密对称 | P0 |
| SEC-006 | RSA 签名 | 签名验证通过 | P1 |
| SEC-007 | EC 签名 | 签名验证通过 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| NET-001 | 以太网连接 | 获取 IP 地址 | P0 |
| NET-002 | WiFi STA | 连接成功 | P0 |
| NET-003 | WiFi AP | 客户端可连接 | P1 |
| NET-004 | HTTP 服务器 | 响应请求 | P0 |
| NET-005 | WebSocket | 双向通信 | P1 |
| NET-006 | HTTPS/mTLS | TLS 握手成功 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| SSH-001 | 密码认证 | 登录成功 | P0 |
| SSH-002 | 公钥认证 (RSA) | 登录成功 | P0 |
| SSH-003 | 公钥认证 (ECDSA) | 登录成功 | P0 |
| SSH-004 | 命令执行 | 返回输出 | P0 |
| SSH-005 | 连接超时 | 正确处理 | P1 |
| SSH-006 | 认证失败 | 返回错误 | P1 |
| SSH-007 | Known Hosts 首次连接 | 提示确认并保存 | P0 |
| SSH-008 | Known Hosts 验证通过 | 静默连接 | P0 |
| SSH-009 | Known Hosts 密钥变更 | 警告并拒绝 | P0 |
| SSH-010 | 交互式 Shell | PTY 分配成功 | P0 |
| SSH-011 | Shell 字符回显 | 立即显示输入 | P0 |
| SSH-012 | Shell Ctrl+C | 发送 SIGINT | P1 |
| SSH-013 | 本地端口转发 | 隧道建立成功 | P1 |
| SSH-014 | 端口转发数据 | 双向转发正确 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| FAN-001 | 速度设置 | PWM 输出正确 | P0 |
| FAN-002 | 转速读取 | Tach 计数正确 | P1 |
| FAN-003 | 自动模式 | 温度曲线工作 | P1 |
| FAN-004 | 加权温度绑定 | 多变量按权重计算有效温度 | P0 |
| FAN-005 | 零总权重拒绝 | 全部权重为 0 的绑定请求被拒绝并保持原配置 | P0 |
| FAN-006 | 部分变量失效 | 不可读变量被跳过,剩余正权重变量继续生效 | P1 |
| FAN-007 | 持久化恢复 | NVS/SD 卡恢复后仍保留有效加权绑定,非法零权重配置被忽略 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| PWR-001 | ADC 电压读取 | 读数准确 (分压比 11.4:1) | P0 |
| PWR-002 | PZEM 电压读取 | UART 通信正常 | P0 |
| PWR-003 | PZEM 电流/功率读取 | 数据准确 | P1 |
| PWR-004 | 警报触发 | 超阈值触发事件 | P1 |
| 测试ID | 测试项 | 预期结果 | 优先级 |
|---|---|---|---|
| DEV-001 | 电源开关 | AGX 正确开关机 | P0 |
| DEV-002 | 复位 | AGX 正确复位 | P0 |
| DEV-003 | 状态检测 | power_good 正确 | P0 |
目的: 验证系统完整启动流程
步骤:
- 冷启动设备
- 观察串口日志
- 验证所有服务启动
验收标准:
- 所有 8 个启动阶段完成
- 无 ERROR 级别日志
- 内存使用在预期范围
目的: 验证 Web 界面完整功能
步骤:
- 连接网络
- 访问 WebUI
- 登录
- 执行 API 调用
- 验证 WebSocket 事件
验收标准:
- 登录成功
- API 返回正确数据
- WebSocket 推送正常
目的: 验证 CLI 和 REST API 行为一致
步骤:
- 通过 CLI 执行命令
- 通过 API 执行相同操作
- 比较结果
验收标准:
- 相同操作返回相同结果
- 状态变更一致
目的: 验证事件系统跨模块工作
步骤:
- 触发硬件事件(如按键)
- 验证事件传播到 LED 模块
- 验证 WebSocket 收到事件
验收标准:
- 事件正确传播
- 延迟 < 100ms
目的: 验证配置在重启后保持
步骤:
- 修改配置
- 重启设备
- 验证配置值
验收标准:
- NVS 配置保持
- 服务使用正确配置
目的: 验证系统稳定性
条件:
- 运行时间: 72 小时
- LED 特效持续运行
- HTTP 请求每 10 秒
验收标准:
- 无崩溃或重启
- 内存无持续增长
- 所有功能正常
目的: 验证 HTTP 服务器并发能力
条件:
- 并发连接: 8
- 请求频率: 100 req/s
- 持续时间: 5 分钟
验收标准:
- 响应时间 < 500ms
- 错误率 < 1%
目的: 验证 WebSocket 广播性能
条件:
- 连接数: 4
- 消息频率: 10 msg/s
- 持续时间: 10 分钟
验收标准:
- 消息无丢失
- 延迟 < 100ms
目的: 验证低内存情况下的行为
条件:
- 分配内存直到 free_heap < 50KB
- 执行常规操作
验收标准:
- 返回错误而非崩溃
- 释放后恢复正常
目的: 验证未认证请求被拒绝
步骤:
- 无 Token 访问受保护 API
- 使用无效 Token
- 使用过期 Token
验收标准:
- 返回 401 Unauthorized
目的: 验证权限检查有效
步骤:
- 使用普通用户 Token
- 访问需要 ADMIN 权限的 API
验收标准:
- 返回 403 Forbidden
目的: 验证恶意输入被过滤
步骤:
- 发送超长字符串
- 发送特殊字符
- 发送畸形 JSON
验收标准:
- 返回错误而非崩溃
- 无缓冲区溢出
目的: 验证 TLS 安全配置
步骤:
- 尝试 TLS 1.0/1.1 连接
- 尝试弱密码套件
验收标准:
- 仅接受 TLS 1.2+
- 仅接受强密码套件
目的: 验证客户端证书验证
步骤:
- 无客户端证书连接
- 使用无效证书连接
- 使用有效证书连接
验收标准:
- 无证书/无效证书被拒绝
- 有效证书通过
| 指标 | 目标值 | 测量方法 |
|---|---|---|
| 启动时间 | < 3 秒 | 从复位到 Ready 日志 |
| 空闲内存 | > 150 KB | heap_caps_get_free_size() |
| HTTP 响应时间 | < 100 ms | curl 测量 |
| LED 刷新率 | 60 Hz | 示波器测量 |
| 事件延迟 | < 10 ms | 日志时间戳 |
| 模块 | 指标 | 目标值 |
|---|---|---|
| ts_config | 读取延迟 | < 1 ms |
| ts_event | 事件处理 | < 1 ms |
| ts_crypto (SHA256) | 1KB 哈希 | < 5 ms |
| ts_crypto (AES-GCM) | 1KB 加密 | < 10 ms |
| ts_led | 单帧渲染 | < 5 ms |
| ts_storage | 文件读取 (4KB) | < 50 ms |
# 在主机上运行单元测试
cd TianShanOS
idf.py -T ts_config test
idf.py -T ts_event test
# ... 其他模块
# 在目标硬件上运行
idf.py flash monitor# 使用 pytest 运行集成测试
cd TianShanOS/tests
pytest test_integration.py -v --target /dev/ttyUSB0# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup ESP-IDF
uses: espressif/esp-idf-ci-action@v1
- name: Run tests
run: idf.py build测试执行报告
============
日期: YYYY-MM-DD
版本: X.Y.Z
测试人员: [名称]
测试环境:
- 硬件: ESP32S3 RM01
- 固件版本: 0.1.0
- ESP-IDF: v5.5.1
测试结果汇总:
- 总用例数: XX
- 通过: XX
- 失败: XX
- 跳过: XX
- 通过率: XX%
失败用例详情:
| 用例ID | 描述 | 失败原因 |
|-------|------|---------|
| XXX-001 | ... | ... |
问题列表:
1. [问题描述] - 严重程度 - 状态
| 阶段 | 时间 | 内容 |
|---|---|---|
| Phase 1 | Week 1-2 | 核心模块单元测试 (ts_config, ts_event, ts_service) |
| Phase 2 | Week 3-4 | HAL 模块测试 (GPIO, PWM, I2C, SPI, UART, ADC) |
| Phase 3 | Week 5-6 | 功能模块测试 (LED, Storage, Console, Security) |
| Phase 4 | Week 7 | 网络模块测试 (Net, SSH, HTTPS) |
| Phase 5 | Week 8 | 集成测试 + 压力测试 |
| Phase 6 | Week 9-10 | 安全测试 + 性能优化 |
| Phase 7 | Week 11-12 | 回归测试 + 文档完善 |