部署、烧录与测试
本文把 FastBee-Arduino 从在线烧录、源码构建、打包发布到真实设备验证的关键命令放在一处,适合开发调试、现场部署、发布打包和量产前核对。第一次体验可直接看 快速开始,浏览器烧录可直接打开 在线烧录工具。
参考来源:源码仓库 FastBee-Arduino 和当前设备端发布脚本说明。
流程总览
固件与环境选择
先按硬件选择 PlatformIO 环境,避免固件与 Flash/PSRAM 不匹配。
| 环境 | 芯片 | Flash / PSRAM | 适用场景 |
|---|---|---|---|
esp32-F4R0 | ESP32 | 4MB / 无 | 普通 ESP32 开发板,默认量产 |
esp32-F8R0 | ESP32 | 8MB / 无 | ESP32-WROOM OTA 节点 |
esp32-F8R8 | ESP32 | 8MB / 8MB | ESP32-WROVER 网关/缓存 |
esp32c3-F4R0 | ESP32-C3 | 4MB / 无 | 低成本 WiFi/MQTT 节点 |
esp32c6-F4R0 | ESP32-C6 | 4MB / 无 | WiFi 6 低成本节点 |
esp32c6-F8R0 | ESP32-C6 | 8MB / 无 | WiFi 6 OTA 节点 |
esp32s3-F8R0 | ESP32-S3 | 8MB / 无 | S3 无 PSRAM OTA 节点 |
esp32s3-F8R8 | ESP32-S3 | 8MB / 8MB | 主力开发/控制器 |
esp32s3-F16R8 | ESP32-S3 | 16MB / 8MB | 完整功能、长稳和发布推荐 |
所有 9 个环境共享统一功能基线,并通过运行时预算与 Web 功能配置按需启用;OTA、红外等硬件能力仍有环境级覆盖。文件名中的 F 表示 Flash 容量,R 表示 PSRAM 容量;F4R0 不改成 N4R0,标准清单不再使用 F8R4,4MB PSRAM 仅作为厂商自定义配置。
在线烧录
普通体验和现场快速恢复优先使用 在线烧录工具。内置固件是合并镜像,包含 bootloader、分区表、应用固件和 LittleFS Web 文件系统,烧录地址固定为 0x0。
- 使用 Chrome 或 Edge 打开在线烧录工具。
- 连接 ESP32 开发板并选择串口。
- 选择与芯片、Flash、PSRAM 匹配的内置固件。
- 地址保持
0x0,点击烧录并等待自动复位。
合并固件已经包含所有分区,无需再分别烧录其他文件。默认外设和执行规则都是安全模板,首次接线请先确认引脚和供电。
如果烧录后页面异常,先确认固件环境与硬件(Flash/PSRAM)匹配;切换分区表或旧配置异常时可先擦除整片 Flash 再重新烧录。
从源码部署
开发调试推荐使用统一部署脚本。脚本会先检查环境,若 data/www/*.gz 不存在则自动调用 node scripts/gzip-www.js 生成 Web 资源,再构建并上传当前环境对应的 LittleFS Web 文件系统和固件。脚本支持 Windows、Linux 和 macOS(后两者需安装 PowerShell Core)。
# Windows
cd D:\project\gitee\FastBee-Arduino
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32-F4R0 -Port COM6
# Linux / macOS(需安装 pwsh)
pwsh -File scripts/deploy.ps1 -Env esp32-F4R0 -Port /dev/ttyUSB0常用部署命令:
# ESP32 4MB 发布环境
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32-F4R0 -Port COM6
# ESP32-S3 16MB + 8MB PSRAM 发布环境
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32s3-F16R8 -Port COM6
# 只构建,不烧录
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32s3-F16R8 -BuildOnly
# 部署后打开串口监视器
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32s3-F16R8 -Port COM6 -Monitor
# 显示完整编译输出,用于排查编译失败
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32s3-F16R8 -Port COM6 -FullOutput分开部署时使用:
# 只更新 LittleFS Web 文件系统
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32s3-F16R8 -Port COM6 -SkipFirmware
# 只更新应用固件
powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Env esp32s3-F16R8 -Port COM6 -SkipFsdeploy.ps1 适合日常使用。需要直接调用 PlatformIO 时,可使用以下兜底命令:
# 编译
pio run -e esp32s3-F16R8
# 上传应用固件
pio run -e esp32s3-F16R8 -t upload --upload-port COM6
# 上传 LittleFS
pio run -e esp32s3-F16R8 -t uploadfs --upload-port COM6
# 串口监视
pio device monitor --port COM6 --baud 115200打包发布产物
准备交付或量产烧录包时,生成所有环境的发布产物:
powershell -ExecutionPolicy Bypass -File scripts\build-all-artifacts.ps1 -CleanOutput重点检查输出目录:
dist/firmware/all-latest/
├── fastbee-esp32-F4R0.bin
├── fastbee-esp32-F8R0.bin
├── fastbee-esp32-F8R8.bin
├── fastbee-esp32c3-F4R0.bin
├── fastbee-esp32c6-F4R0.bin
├── fastbee-esp32c6-F8R0.bin
├── fastbee-esp32s3-F8R0.bin
├── fastbee-esp32s3-F8R8.bin
├── fastbee-esp32s3-F16R8.bin
└── manifest.json这些 .bin 是合并固件,适合在线烧录工具、flash-release.ps1、esptool.py 或量产烧录工具使用。发布前必须核对 manifest.json 中的环境、文件大小和 SHA-256。
直接烧录发布包
已生成发布包后,可以跳过本地编译,直接写入合并固件:
# 推荐封装脚本,会按 Env 找到 dist/firmware/all-latest 中的合并固件
powershell -ExecutionPolicy Bypass -File scripts\flash-release.ps1 -Env esp32s3-F16R8 -Port COM6
# 预览命令,不实际烧录
powershell -ExecutionPolicy Bypass -File scripts\flash-release.ps1 -Env esp32s3-F16R8 -Port COM6 -DryRun也可以直接使用 esptool.py:
# 可选:切换分区表或旧配置异常时先擦除
esptool.py --chip auto --port COM6 erase_flash
# 从 0x0 写入合并固件
esptool.py --chip auto --port COM6 --baud 921600 write_flash -z 0x0 dist\firmware\all-latest\fastbee-esp32s3-F16R8.bin首次访问与部署验证
设备首次启动或 WiFi 未配置时会进入 AP 模式。
| 项目 | 默认值 |
|---|---|
| WiFi 热点 | apSSID 为空时为 设备名-芯片ID前6位;恢复出厂设置后为 fastbee-ap |
| 浏览器地址 | http://192.168.4.1 或 http://fastbee.local |
| 用户名 | admin |
| 密码 | admin123 |
烧录完成后按以下顺序验证:
- 登录 Web 控制台,确认仪表盘能显示运行时间、Heap、Flash 和网络状态。
- 在网络配置页配置 WiFi、以太网或 4G,并确认重新上线。
- 配置 MQTT 或 Modbus,确认协议状态正常。
- 添加一个实际接线的外设,先禁用保存,再单项启用验证。
- 新增一条简单外设执行规则,先手动执行,再启用自动触发。
- 导出配置、保留截图、串口日志和发布包
manifest.json。

默认外设模板和执行规则都应保持出厂禁用。现场接线确认前不要启用继电器、电机、Modbus 写入、系统重启或 OTA 等强动作。
测试分层
测试分层从低成本到高真实性逐层推进;日常开发优先跑底层,发布验收必须覆盖真机和长稳层。
| 层级 | 命令入口 | 覆盖内容 | 何时执行 |
|---|---|---|---|
| 静态检查 | scripts\test-all.ps1 -Checks static | UTF-8、测试注册、API 矩阵、构建矩阵、文档链接、默认配置安全性、i18n、Web 静态资源、Git 空白检查 | 每次提交前 |
| native 单元测试 | scripts\test-all.ps1 -Checks native | host 侧 C++ 单元测试(含 CommandBus、ErrorHandler、OTA、RuleScript、Batch/SSE、PeriphExec、防变砖源码锁定) | 修改核心逻辑/API/配置解析时 |
| 全版本编译 | scripts\test-all.ps1 -Checks build | 9 个发布环境:ESP32、ESP32-C3、ESP32-C6、ESP32-S3 的 Flash/PSRAM 组合 | 每次影响固件或编译开关时 |
| 发布产物 | scripts\test-all.ps1 -Checks artifacts | 合并固件、LittleFS、manifest.json | 准备发布或交付烧录包时 |
| 设备冒烟 | scripts\test-all.ps1 -Checks device-smoke | 登录、系统、版本能力、网络、设备配置、协议、MQTT、外设、外设执行、日志/文件/OTA 及按能力暴露的用户/权限 API | 烧录真实设备后 |
| 设备稳定性 | scripts\test-all.ps1 -Checks device-soak | 多轮 API 循环、版本能力、低内存保护、认证稳定性和响应耗时 | 关键改动后和发布前 |
| 浏览器快速 | scripts\test-all.ps1 -Checks browser-quick | 当前 @quick 核心用例:登录/仪表盘/网络/MQTT/外设/规则 | 日常开发和固件冒烟 |
| 页面巡检 | scripts\device-web-smoke.ps1 | 16 个公开页面的 HTTP 200、耗时和响应大小;支持轮次、间隔和 CSV 报告 | 每次烧录后、低内存设备和发布前 |
| 浏览器完整 | scripts\test-all.ps1 -Checks browser | test/browser 中的 Playwright 用例:登录、页面交互和边界场景 | 发布前完整回归 |
版本矩阵
| PlatformIO 环境 | 芯片/硬件 | 必跑检查 |
|---|---|---|
esp32-F4R0 | ESP32 4MB Flash / 无 PSRAM | static、native、build、设备冒烟 |
esp32-F8R0 | ESP32 8MB Flash / 无 PSRAM | static、build、设备冒烟 |
esp32-F8R8 | ESP32 8MB Flash / 8MB PSRAM | static、build、设备冒烟 |
esp32c3-F4R0 | ESP32-C3 4MB Flash / 无 PSRAM | static、build、设备冒烟 |
esp32c6-F4R0 | ESP32-C6 4MB Flash / 无 PSRAM | static、build、设备冒烟 |
esp32c6-F8R0 | ESP32-C6 8MB Flash / 无 PSRAM | static、build、设备冒烟 |
esp32s3-F8R0 | ESP32-S3 8MB Flash / 无 PSRAM | static、build、设备冒烟 |
esp32s3-F8R8 | ESP32-S3 8MB Flash / 8MB PSRAM | static、build、设备冒烟和稳定性测试 |
esp32s3-F16R8 | ESP32-S3 16MB Flash / 8MB PSRAM | static、native、build、artifacts、设备冒烟和稳定性测试 |
4MB 环境使用 partitions/4MB.csv,单应用分区且不支持 OTA;8MB 环境使用 partitions/8MB.csv,提供 OTA 双分区;16MB 环境使用 partitions/16MB.csv,文件系统空间更充裕。
常用测试命令
多板 STA 验证约定
现场验证使用设备当前的 STA 地址,不连接设备 AP,避免让测试电脑断网。仓库文档不固定实验室 DHCP 地址;每次测试前都应从串口启动日志或路由器 DHCP 客户端表确认地址,并在本地舰队配置中用 <device-ip> 的实际值替换占位符。配置来源必须与串口和环境一一对应,不能互换:
| 串口 | 环境 | STA 地址 | 配置来源 |
|---|---|---|---|
| COM4 | esp32c3-F4R0 | <device-ip> | docs/esp32c3-deployment-config.json |
| COM11 | esp32c6-F4R0 | <device-ip> | docs/c6-rgb-led-f4r0/ |
| COM15 | esp32s3-F16R8 | <device-ip> | docs/ecm50a-s3-f16r8/ |
| COM16 | esp32-F4R0 | <device-ip> | docs/puzhong-esp32-config.json |
| COM7 | esp32s3-F8R0 | <device-ip> | docs/waveshare-esp32s3-relay6ch/ |
导入选定配置包并按内存策略部署(脚本会在结束时恢复仓库默认配置):
powershell -ExecutionPolicy Bypass -File scripts\deploy-config-bundle.ps1 `
-Env esp32-F4R0 -Port COM16 `
-BundlePath docs\puzhong-esp32-config.json -MemoryProfile auto完成烧录后先跑 16 个页面两轮,再启动长期监测;STA 未联网的设备只记录串口原因并跳过其 HTTP 检查,不切换到 AP。
powershell -ExecutionPolicy Bypass -File scripts\device-web-smoke.ps1 `
-BaseUrl http://<device-ip> -Rounds 2 -DelayMs 1000 `
-TimeoutSec 15 -MaxElapsedMs 5000 -ReportPath test\reports\f4-web.csv
powershell -ExecutionPolicy Bypass -File scripts\long-term-device-monitor.ps1 `
-DurationHours 8 -IntervalSeconds 60
$runDir = "artifacts/final-stability-{0}" -f (Get-Date -Format "yyyyMMdd-HHmmss")
node test/browser/fleet-stability-monitor.mjs `
--interval 180 --max-cycles 161 --min-duration-hours 8 `
--report-every 8 --cycle-timeout 420 --output-dir $runDir长期监测脚本遇到 HTTP/串口失败、覆盖缺口或 uptime 回退会以非零状态结束。浏览器监测还要求每台设备的实际首末样本窗口不少于 8 小时,并对在线、登录、全部可见菜单、HTTP/控制台/页面错误、重试、WebGuard 503、内部 DRAM、最大连续块及响应 p95 执行严格门禁。只有进程退出码为 0 且生成的 fleet-stability-verdict.json 为 PASS 才能记录为通过;命令示例不代表已完成真机验收。
所有测试的统一入口是 scripts\test-all.ps1,通过 -Checks 指定检查项,支持多项组合。
# 快速提交前检查(静态 + 构建)
powershell -ExecutionPolicy Bypass -Command ".\scripts\test-all.ps1 -Checks static,build"
# 完整本地矩阵,不访问真实设备
powershell -ExecutionPolicy Bypass -Command ".\scripts\test-all.ps1 -Checks static,native,build,artifacts"
# 真实设备 API 冒烟测试
powershell -ExecutionPolicy Bypass -File scripts\test-all.ps1 -Checks device-smoke -BaseUrl http://<device-ip> -DeviceProfile unified
# 16 个 Web 页面,低内存设备保留 1 秒请求间隔
powershell -ExecutionPolicy Bypass -File scripts\device-web-smoke.ps1 -BaseUrl http://<device-ip> -Rounds 2 -DelayMs 1000 -TimeoutSec 15 -MaxElapsedMs 5000 -ReportPath test\reports\web-smoke.csv
# 真实设备长期稳定性测试,输出 CSV 到 .pio/test-results
powershell -ExecutionPolicy Bypass -File scripts\test-all.ps1 -Checks device-soak -BaseUrl http://<device-ip> -DeviceProfile unified -SoakRounds 100
# 快速浏览器测试(日常开发推荐)
powershell -ExecutionPolicy Bypass -File scripts\test-all.ps1 -Checks browser-quick -BaseUrl http://<device-ip> -DeviceProfile unified
# 完整浏览器测试(发布前回归)
powershell -ExecutionPolicy Bypass -File scripts\test-all.ps1 -Checks browser -BaseUrl http://<device-ip> -DeviceProfile unified
# 一次跑多项检查
powershell -ExecutionPolicy Bypass -File scripts\test-all.ps1 -Checks static,build,device-smoke,browser-quick -BaseUrl http://<device-ip> -DeviceProfile unified-Checks 可选值
| 值 | 说明 | 是否需要设备参数 |
|---|---|---|
static | 静态检查:UTF-8、测试注册、API 矩阵、构建矩阵、文档链接、默认配置安全性、i18n、Web 静态资源、Git 空白 | 否 |
native | Host 侧 C++ 单元测试(CommandBus、ErrorHandler、OTA、RuleScript、Batch/SSE、PeriphExec、防变砖源码锁定) | 否 |
build | 9 个出厂环境统一固件编译(ESP32/C3/C6/S3 的 Flash/PSRAM 组合) | 否 |
artifacts | 生成合并固件、LittleFS、manifest.json 发布产物 | 否 |
device-smoke | 设备 API 冒烟:登录、系统、能力、网络、设备、协议、MQTT、外设、日志/文件/OTA/用户 | 是 |
device-soak | 设备长稳:多轮 API 循环、低内存保护、认证稳定性、响应耗时 | 是 |
browser-quick | 当前 @quick 核心用例:登录/仪表盘/网络/MQTT/外设/规则 | 是 |
browser | test/browser 中的全量 Playwright 用例:所有页面交互和边界场景 | 是 |
all | 运行全部检查项(等同于上面所有值) | 是 |
-BaseUrl和-DeviceProfile在访问真实设备的检查项(device-smoke、device-soak、browser-quick、browser)中必须传入,否则会因无法连接设备而报错。
常用参数
| 参数 | 默认值 | 说明 |
|---|---|---|
-Checks | static,native,build | 要执行的检查项,支持多项 |
-BaseUrl | 空 | 真机检查必须显式传入 STA 地址;脚本拒绝设备 AP 地址 192.168.4.1 |
-DeviceProfile | unified | 统一能力断言配置,不是固件产品版本 |
-Username / -Password | admin / admin123 | Web 登录凭据 |
-SoakRounds | 10 | 长稳测试循环次数 |
-Environments | 全部 9 个 | 指定要编译的 PlatformIO 环境 |
-ContinueOnError | false | 某项失败后继续执行后续检查 |
-DeviceSerial | 空 | 浏览器测试时指定串口(用于设备预检) |
-BrowserHeaded | false | 浏览器测试显示窗口(调试用) |
-ReportDir | .pio\test-results | 长稳 CSV 报告输出目录 |
-RequireNetworkConnected | false | 冒烟测试要求设备已联网 |
-RequireMqttConnected | false | 冒烟测试要求 MQTT 已连接 |
如果本地 Windows 环境缺少 gcc/g++,native 会失败。这不是固件编译失败,需要先安装 MinGW/MSYS2 或在 CI/Linux 环境执行 native 测试。
-DeviceProfile 仅支持 unified,用于当前统一能力断言;该参数保留命令兼容性,不是产品档位。实际预期还须结合设备返回的编译能力、用户配置和硬件资源,不能通过测试参数划分固件产品版本。
断言必须区分“未编译”和“已编译但未启用”:
- 路由是否注册取决于编译能力,功能是否运行取决于配置和资源状态。已禁用不必然等于接口不存在,未编译也不能强制要求接口可用;按各接口契约核验状态码和响应内容。
/api/system/capabilities不含tcp/http/coap字段,能力断言不应检查这些键。
此外 unified 固件允许 MQTT 处于禁用状态:此时 initialized=false 属于正常语义,冒烟测试应视为通过而非失败。
浏览器自动化测试
浏览器测试使用 Playwright 自动操作设备 Web 控制台,覆盖登录、仪表盘、网络/设备/MQTT 配置、外设管理、规则脚本、日志和用户等页面交互,并通过集成用例检查定制固件的可选文件 API。
快速 vs 完整测试
| 模式 | 配置文件 | 用例数 | 预估时间 | 适用场景 |
|---|---|---|---|---|
快速 (browser-quick) | playwright.quick.config.ts | 当前 @quick 用例集 | 以设备响应为准 | 开发阶段快速验证、固件冒烟 |
完整 (browser) | playwright.config.ts | 当前全量用例集 | 以设备响应为准 | 发布前完整验收、深度回归测试 |
快速测试通过 @quick 标签从每个 spec 文件中筛选核心用例,覆盖认证、仪表盘、网络配置、设备信息、MQTT 通信、外设 CRUD、规则脚本、日志、用户管理和可选文件 API 等关键路径。
Playwright 直连运行
不经过 test-all.ps1,直接调用 Playwright 可以获得更细粒度的控制:
cd test\browser
$env:DEVICE_IP = "<device-ip>"
# 运行快速 / 完整测试
npx playwright test -c playwright.quick.config.ts # 快速
npx playwright test # 完整
# 运行指定测试
npx playwright test -g "AUTH-001" # 按名称过滤
npx playwright test -g "@quick" --project=smoke # 组合过滤
# 查看 HTML 报告
npx playwright show-report reports\quick-html # 快速测试
npx playwright show-report reports\html # 完整测试测试时间对比报告
运行快速测试后,执行对比脚本查看与上次完整测试的时间差异:
node scripts\compare-test-timing.js输出包含总时间、每文件耗时分解、Top 10 最慢用例和加速倍数。
@quick 标签维护
核心测试用例标题中包含 @quick 标签,quick 配置通过 --grep @quick 过滤:
test('AUTH-001: 正确凭证登录 @quick', async ({ page }) => { ... });新增测试时,判断是否加入快速集:
- 覆盖核心用户路径(登录、配置保存、协议连接)→ 加
@quick - 边界值、异常场景、详细表单字段验证 → 仅完整测试
进度显示
两种模式都使用 list reporter 实时显示每个测试的通过/失败状态和耗时。快速测试无重试(retries: 0),失败立即报告,适合快速定位问题。
ESP32 Web 并发限流与导航策略
设备端对静态文件并发响应数有上限(当前 3 路),超限请求返回 503 + Retry-After,由前端加载器退避重试。浏览器每 host 默认 6 并发,登录瞬间的资源突发会触发限流,因此:
- 浏览器测试的
page.goto使用waitUntil: 'domcontentloaded'而非load:限流下尾部资源(图片、字体)会拖延load事件导致导航超时;仅17-perf.spec.ts保留完整加载语义用于性能测量。 - 503 响应的 MIME 与请求资源类型匹配(JS 返回 JS 占位、CSS 返回 CSS 占位),避免浏览器严格 MIME 检查拒绝执行产生 console 报错噪音。
- 登录页内联 fallback 会等待 boot chunk 加载完成后再调用登录;若设备负载高导致加载慢,属正常现象,测试会自动等待而非直接判失败。
舰队多设备测试
多台设备同时在线时,用 scripts\run-device-fleet-tests.ps1 一次性对整支舰队执行 STA 验证 + mDNS 验证 + API 冒烟 + 内存泄漏/重启检测:
# 复制示例并按当前 DHCP/串口修改,再从 JSON 加载
Copy-Item scripts\device-fleet.example.json scripts\device-fleet.local.json
# 编辑 scripts\device-fleet.local.json 后执行
powershell -ExecutionPolicy Bypass -File scripts\run-device-fleet-tests.ps1 -DeviceConfig scripts\device-fleet.local.json -Ssid fastbee -BrowserTests:$false
# 也可以通过 -Devices 传入 PowerShell hashtable
$myFleet = @(
@{ Label = 'esp32-F4R0'; IP = '<device-ip>'; Profile = 'unified'; Domain = ''; Serial = 'COM16' }
)
powershell -ExecutionPolicy Bypass -File scripts\run-device-fleet-tests.ps1 -Devices $myFleet -Ssid fastbee舰队脚本对每台设备依次执行:
- 登录验证(admin 凭据)。
- STA 模式验证:
connected=true、SSID 匹配、IP 不在192.168.4.xAP 网段。 - mDNS 域名验证:通过设备实际注册域名(mdnsDomain)访问首页返回 200。
- 前置 heap/uptime 快照 → 调用
smoke-test-device.ps1全量冒烟 → 后置快照。 - 泄漏/重启检测:heap 显著下降或 uptime 重置判为失败。
报告输出到 .pio\test-results\fleet\(JSON + CSV)。
-DeviceConfig 配置项为 label、ip、profile、domain、serial;domain 可以为空以跳过 mDNS 检查。示例文件只提供结构,不构成地址台账;DHCP 变化后以设备串口或路由器租约为准更新本地配置,不要把现场地址提交到公共仓库。
若只检查页面是否可访问,可直接运行:
powershell -ExecutionPolicy Bypass -File scripts\device-web-smoke.ps1 -BaseUrl http://<device-ip> -Rounds 2 -DelayMs 1000 -TimeoutSec 15 -MaxElapsedMs 5000 -ReportPath test\reports\web-smoke.csv该脚本固定覆盖 16 个公开页面,逐项记录 HTTP 状态码、耗时和响应字节数;它不执行写操作,适合烧录后和长稳期间重复执行。-MaxElapsedMs 5000 可作为发布级“流畅”门槛;不传时只以完整 HTTP 200 为通过条件。开始前应确认设备 RSSI,低于约 -75 dBm 时先改善链路,否则弱信号会把网络问题误判为固件页面问题。
多设备 mDNS 域名
同一局域网内多台 FastBee 设备推荐全部使用默认命名(customDomain = fastbee)。固件启动时枚举 _http._tcp 预探测已占用 hostname,自动分配唯一后缀(fastbee、fastbee-2 … fastbee-8),并在运行期每 30s 做同名收敛(IP 大者让名),新设备即插即用无需逐台改名。舰队实测终态示例:
| 设备 | 实际注册域名 |
|---|---|
| ESP32-C3 | fastbee.local |
| ESP32-C6 | fastbee-2.local |
| ESP32-S3 | fastbee-3.local |
设备实际注册的 mDNS 名称以当前构建和运行日志/API 返回为准;不要根据设备标签或上电顺序推断自动后缀。若需要稳定名称,请在网络设置页配置 customDomain,并用 /api/network/status(需登录)或串口日志核对结果。机制详见mDNS 网络。
注意:uploadfs 会写入 LittleFS,可能覆盖设备上的配置文件。对已有现场设备先备份并确认写入范围;部署不同设备配置时使用 scripts/deploy-config-bundle.ps1,不要把公开 data/config 当作现场配置备份。STA 和 MQTT 凭据通过环境变量或显式参数临时注入,不应写入可提交的 JSON。不要手工替换 data/config,也不要复用旧 staging 或外部 PLATFORMIO_DATA_DIR。
设备冒烟覆盖
设备 API 测试共用 scripts\device-api-test-matrix.json。执行冒烟测试时,失败项应立刻记录首个失败接口,首个失败通常最接近根因。
| 类别 | 检查项 |
|---|---|
| 认证 | 登录、Bearer Token 优先级、多会话登录 |
| 系统 | /api/health、/api/system/health、/api/system/info、/api/system/status、/api/system/web-runtime、/api/system/capabilities |
| 系统指标 | /api/system/metrics、heap、memguard、运行时指标 |
| 网络 | /api/network/status、/api/network/config、连接状态、IP、联网类型、AP/STA 配置 |
| 设备 | /api/device/config、/api/device/info、/api/device/time |
| 通信 | MQTT 状态、MQTT 配置、协议紧凑配置、Modbus 状态 |
| 外设 | 外设列表、外设类型、参数缺失错误、执行规则、执行控件、触发器、静态/动态事件、事件分类、批量 API |
| 运行时能力 | 编译开关、用户开关、内存预算三态语义 |
| 扩展接口 | 文件系统、根目录文件列表、日志、OTA、RuleScript,以及按能力状态暴露的用户/权限接口 |
| 能力边界 | 未编译、未启用或预算不足的接口应返回合理不可用状态 |
新增或调整 API 时,先更新 device-api-test-matrix.json,再执行 smoke/soak,确保裁剪行为和状态码都符合预期。
矩阵中普通检查项(无 type)支持 allowedStatuses 数组:命中其中任一 HTTP 状态码即判通过(跳过语义检查),用于表达"固件设计内的确定性非 200 响应"。典型案例:rule-scripts 允许 503——ruleScript 特性默认 userEnabled=false,未启用时 RuleScriptManager 不初始化(mutex 为 NULL),/api/rule-script 恒定返回 503 "Service busy, try again",这是特性开关语义而非故障。新增此类用例时同步确认 /api/features/status 中对应特性的 compiled/userEnabled/active 三态。
断言编写另需注意 PowerShell 5.1 的两个坑:① ConvertFrom-Json 会把空数组 [] 转成 $null,peripherals、periph-exec-rules 等列表型端点在设备无配置时 data 为空数组,不能以 data -eq $null 判失败;② capabilities 断言不得检查固件已移除的字段(当前能力接口没有 tcp/http/coap),无 PSRAM 机型也不能强制要求 psramTotal>0。
统一固件稳定性验收底线
当前发布环境共享功能基线,差异来自芯片资源、分区、环境级覆盖和运行时开关。发布前至少确认:
| 验收项 | 统一发布环境要求 |
|---|---|
| 上电、WiFi/AP 配网、网络和 MQTT 恢复 | 必须通过 |
| 配置异常保护、看门狗和健康监控 | 必须通过 |
| 关键日志、故障码和能力状态 | 必须可观测 |
| OTA | 仅对 8MB/16MB 双 app 环境验证;4MB 标记为不支持 |
| 远程配置、外设和规则 | 按编译/运行时能力验证 |
| 长稳测试 | 当前版本至少完成 24 小时;关键发布建议 72 小时至 7 天 |
冒烟测试清单
冒烟测试用于判断当前固件是否具备继续功能测试和交付验证的条件。任一必测项失败,都不应进入长稳测试。
| 编号 | 测试项 | 适用范围 | 通过标准 |
|---|---|---|---|
| SMK-01 | 九个发布环境编译 | 全部 | 对应 PlatformIO 环境无编译错误 |
| SMK-02 | 固件和 LittleFS 烧录 | 目标硬件 | 串口烧录完成,设备自动重启 |
| SMK-03 | 上电和文件系统 | 全部 | 启动日志正常,/config/*.json 可读取 |
| SMK-04 | AP/STA 与 Web 健康 | 全部 | AP 可访问,STA 配网后有 IP,/api/health 正常 |
| SMK-05 | 编译和运行时能力 | 全部 | /api/system/capabilities、/api/features/status、/api/system/status 语义一致 |
| SMK-06 | MQTT、数据上报和命令 | 已启用 MQTT | 连接成功,平台能收发一条消息 |
| SMK-07 | 外设和规则 | 已配置模块 | 手动执行和自动触发结果一致 |
| SMK-08 | Modbus 主站 | 已启用 Modbus | 从站轮询和读写状态正常 |
| SMK-09 | OTA | 8MB/16MB 双 app 环境 | 状态接口可用并能完成验证升级;4MB 明确不可用 |
| SMK-10 | 日志、用户和配置迁移 | 对应功能已编译/启用 | API 可用,禁用时返回合理状态 |
推荐命令(统一入口详见 常用测试命令):
# 静态 + 构建检查
powershell -ExecutionPolicy Bypass -Command ".\scripts\test-all.ps1 -Checks static,build"
# 设备冒烟(要求网络和 MQTT 已连接)
powershell -ExecutionPolicy Bypass -File scripts\test-all.ps1 -Checks device-smoke -BaseUrl http://<device-ip> -DeviceProfile unified -RequireNetworkConnected -RequireMqttConnected功能测试用例矩阵
功能测试按模块验证完整业务行为。新增外设、协议、接口或版本裁剪开关时,应同步补充用例。
| 编号 | 模块 | 用例 | 预期结果 |
|---|---|---|---|
| FUN-01 | 启动/网络 | 首次启动、AP 配网、STA 重连、静态 IP | 配置可保存,重启和断网后能恢复 |
| FUN-02 | 设备配置 | 设备名、时区、基础参数修改 | 校验、保存和重启恢复正常 |
| FUN-03 | MQTT | 连接、订阅、发布、遗嘱消息 | 平台在线状态和消息流正确 |
| FUN-04 | 外设 | GPIO/ADC/传感器读取 | 数据格式正确,无异常阻塞 |
| FUN-05 | 自动化 | 定时、事件、平台、轮询触发 | 条件判断和动作执行符合配置 |
| FUN-06 | Modbus | 从站扫描、寄存器轮询、控制 | 异常从站不阻塞主循环 |
| FUN-07 | Web/认证 | 登录、Bearer Token、多会话 | 权限与会话状态正确 |
| FUN-08 | 日志/配置 | 日志查看、配置导入导出 | 低内存时合理降级,配置不损坏 |
| FUN-09 | 用户/脚本 | 权限边界、脚本保存和异常处理 | 未授权被拒绝,脚本失败不影响主循环 |
| FUN-10 | OTA | 上传、URL 升级、状态查询 | 双 app 环境升级成功,4MB 拒绝 |
| FUN-11 | 边界/资源 | 非法 JSON、低内存、并发 API、SSE | 返回合理错误,系统继续运行 |
发布前清单
- 执行
scripts\test-all.ps1 -Checks static,native,build,artifacts。 - 分别烧录目标芯片,并确认
deploy.ps1的-Env与芯片版本一致。 - 执行
node scripts\validate-config-defaults.js --staging-root .pio\fs-staging --latest-only。 - 确认默认
peripherals.json外设模板和periph_exec.json规则没有出厂启用。 - 对每个实际交付版本执行一次设备冒烟测试(
-Checks device-smoke)。 - 执行快速浏览器测试(
-Checks browser-quick),确认核心页面交互正常。 - 对
esp32s3-F16R8和其他高负载交付目标执行至少 100 轮 soak。 - 检查
/api/system/info的 heap、maxAlloc、PSRAM 和运行时功能状态是否符合预期。 - 检查 Web 页面:登录、网络设置、设备配置、通信协议、外设配置、外设执行、日志,以及已启用的用户管理和规则脚本;在设备配置中验证配置导入/导出。
- 生成发布产物并核对
dist\firmware\all-latest\manifest.json。
断网重连测试
断网重连测试重点验证无人值守现场的自动恢复能力。所有发布环境都必须执行;以太网或 4G 仅在对应硬件和编译开关启用时覆盖。
| 编号 | 场景 | 操作步骤 | 通过标准 |
|---|---|---|---|
| NET-01 | 启动前无网络 | 断开路由器或输入不可用 SSID 后上电 | 设备保持 AP/Web 可访问,不死机,不频繁重启 |
| NET-02 | 运行中断开 WiFi | 设备在线后关闭路由器 5 分钟 | 日志记录断线,主循环继续运行,MQTT 不阻塞 |
| NET-03 | 网络恢复 | 恢复路由器或信号 | 设备自动获取 IP,MQTT 自动重连,平台重新在线 |
| NET-04 | MQTT 服务不可达 | 停止 broker 或阻断端口 | 设备进入退避重连,不影响本地 Web 和外设执行 |
| NET-05 | DNS 解析失败 | 配置错误域名或阻断 DNS | 返回连接失败状态,恢复 DNS 后自动连接 |
| NET-06 | 弱网/高延迟 | 增加丢包或限速 | 请求超时可恢复,无内存持续下降 |
| NET-07 | 网络类型切换 | WiFi/以太网/4G 按配置切换 | /api/network/status 与 MQTT Client 类型一致 |
验收指标:网络恢复后 3 分钟内自动上线;断网期间不进入无限重启;MQTT 重连后至少完成一次属性或状态上报;heapFree 和 heapMaxAlloc 不持续恶化。
掉电恢复测试
掉电恢复测试用于验证配置保护、文件系统一致性和升级失败保护。执行掉电测试前先备份现场配置。
| 编号 | 场景 | 操作步骤 | 通过标准 |
|---|---|---|---|
| PWR-01 | 普通运行中掉电 | 设备稳定在线后直接断电,再上电 | 配置不丢失,设备自动恢复在线 |
| PWR-02 | 数据上报中掉电 | 连续上报时断电 | 重启后主循环、MQTT 和外设状态正常 |
| PWR-03 | 配置保存中掉电 | 修改网络/设备/协议配置时断电 | 旧配置或新配置至少有一个可用,不出现损坏 JSON |
| PWR-04 | 文件系统更新中掉电 | 导入配置或更新 LittleFS 时断电 | 文件系统可挂载,异常文件可重新写入 |
| PWR-05 | OTA 上传中掉电 | 8MB/16MB 双 app 环境升级上传中断电 | 重启后旧固件仍可启动或进入可恢复状态 |
| PWR-06 | OTA 校验失败 | 上传错误包或错误 SHA-256 | 升级中止,返回 ERR_OTA_VERIFY_FAILED 或等价状态 |
| PWR-07 | 高频重启 | 连续上电/断电 10 次 | 无配置丢失、无启动卡死、无异常 Flash 写入 |
长稳测试报告模板
长稳测试建议每种目标硬件单独出报告;当前版本至少完成 24 小时,关键发布建议 72 小时至 7 天。报告要保留趋势判断:最小 heapFree、最小 heapMaxAlloc、失败率和首次失败前后的接口耗时。
项目名称:FastBee-Arduino 嵌入式物联网软件系统
测试类型:长稳测试
测试版本:
测试断言集:unified
PlatformIO 环境:
硬件型号:
Flash/PSRAM:
固件 SHA-256:
LittleFS SHA-256:
测试地点/网络环境:
平台/Broker 地址:
测试开始时间:
测试结束时间:
累计运行时长:
关键指标:
- 异常重启次数:
- 网络断线次数:
- 自动恢复次数:
- MQTT 断线次数:
- 数据上报总数:
- 数据上报成功率:
- 命令下发总数:
- 命令响应成功率:
- 最小 heapFree:
- 最小 heapMaxAlloc:
- 带 PSRAM 环境的 psramTotal/psramFree:
- 低内存保护触发次数:
- OTA 状态检查次数:
- 故障码统计:
结论:
- 通过 / 不通过:
- 遗留问题:
- 发布建议:推荐稳定性指标:
| 指标 | 建议门槛 |
|---|---|
| 连续运行 | >= 24 小时;关键发布建议 72 小时至 7 天 |
| 异常重启 | 0 次 |
| 网络恢复 | 100% 自动恢复 |
| 数据上报成功率 | >= 99% |
| 命令响应成功率 | >= 99% |
| 内存趋势 | heap 不持续下降;带 PSRAM 环境同时检查 PSRAM |
常见问题
找不到串口
确认 USB 线支持数据传输,安装 CH340、CP210x 等串口驱动(驱动下载见下载中心),并关闭 Arduino IDE、PlatformIO Monitor 或其他占用串口的软件。
一直等待同步
部分开发板自动下载电路不稳定。按住 BOOT 后开始烧录,看到写入日志后松开;失败后按 EN / RST 重启再试。
上传后 Web 控制台打不开
优先确认是否上传了 LittleFS。只用 pio run -t upload 会更新应用固件,但不会更新 Web 文件系统;日常部署建议用 deploy.ps1 或先 uploadfs 再 upload。
带 PSRAM 环境运行不稳定
检查实际硬件是否带 PSRAM,并在 /api/system/info 或启动日志中确认 psramTotal > 0。统一固件烧录到无 PSRAM 硬件上(如 esp32s3-F8R8 烧到无 PSRAM 的 S3 板)容易触发低内存保护。
发布包烧录后配置异常
切换不同分区表、不同 Flash 容量或从其它固件迁移时,先擦除整片 Flash,再烧录合并固件。擦除会清空网络、外设和规则配置,现场执行前必须备份。
-DeviceProfile 不匹配
-DeviceProfile 只接受 unified,设备能力差异由实际能力接口与测试契约判断。浏览器登录问题优先用 smoke 测 Bearer Token,避免陈旧 Cookie 干扰。
native 测试编译失败
Windows 环境缺少 gcc/g++ 时 native 会报编译错误,这不是固件问题。安装 MinGW/MSYS2 或在 CI/Linux 环境执行 native 测试即可。
浏览器测试超时失败
优先检查设备 IP 是否正确(-BaseUrl)、设备是否在线(ping 或访问 Web 页面)。globalSetup 预检会输出设备可达性警告。网络配置变更后设备可能临时不可达,测试内置了 cleanup 恢复逻辑。
浏览器测试结果不一致
同一用例偶尔通过偶尔失败时,检查是否有其它进程占用设备串口或 Web 端口。降低 TEST_DELAY_MS(如 300)可加速但可能增加不稳定性;增大到 800 可提高稳定性。完整测试有自动重试(retries: 2),快速测试无重试(retries: 0)。
浏览器测试出现大量 503 或资源加载失败
设备端静态文件并发上限为 3 路,浏览器并发突发会触发 503 + Retry-After 限流,前端加载器会自动退避重试。若持续失败:确认测试机与设备在同一局域网且串行 curl 访问正常;确认没有其它进程(多个测试实例、浏览器页面)同时压测同一台设备;舰队测试请逐台或错峰执行。
soak 测试内存指标持续下降
heapFree 或 heapMaxAlloc 持续下降通常是内存泄漏。先确认固件版本是否已包含 MQTTS 内存优化(memguard 降级机制),再检查 /api/system/metrics 中的 heapMinFree 历史最小值;带 PSRAM 的环境同时关注 psramFree 趋势。
无 PSRAM 设备频繁重启(Web 负载下 DRAM 耗尽)
浏览器自动化或并发访问期间设备间歇性不可达,且 /api/health 的 timestamp 反复回到较小值,通常表示设备发生了重启。先检查串口 STATUS 的 free8、blk8 和 [MemGuard] 日志,再降低并发、关闭未使用功能或降低轮询频率;仍无法保留足够余量时应改用带 PSRAM 的环境。
ESP32-S3 开机后每 ~10s 重启(USB CDC 阻塞 / 保留引脚)
S3 设备反复 TG1WDT_SYS_RST 且缺少普通 Serial 日志时,先确认板卡使用原生 USB 还是 CH340/CH343 串口桥,并检查 ARDUINO_USB_CDC_ON_BOOT 是否匹配。需要覆盖该设置时建立专用环境验证,不要直接修改全部 S3 发布环境。外设引脚还必须避开 include/core/ChipConfig.h 中对应芯片和 Flash/PSRAM 模式的保留引脚。
浏览器套件每个用例都触发 [RECOVERY] RTS reset pulse
若每个用例前都打印 Device unreachable, attempting serial reset,先确认健康探针使用无需鉴权的 /api/health。受保护接口返回 401 不能判定为设备离线;修改探针后应先用无 Cookie 请求验证返回码,再允许脚本触发串口恢复。
长期稳定性采样
使用 scripts/soak-test-device.ps1 对 /api/health、网络状态及配置的只读端点持续采样。bootMs 应单调增长,heapFree 和 heapMaxAlloc 不应持续下降。偶发超时需要结合 RSSI、串口重启日志和后续恢复情况判断;不要让多个测试进程同时压测同一设备。
classic ESP32 浏览器测试频繁自愈复位
classic ESP32 的内部 DRAM 余量较小,浏览器连接与后台轮询叠加时可能触发 Web 保护或探针超时。生产部署应选择匹配容量的发布环境,关闭未使用功能,并串行或错峰执行页面测试。不能仅凭自动恢复后用例通过就判定稳定,仍需核对重启计数和 heap 趋势。
ESP32-C3 每次复位必进下载模式 / USB 枚举循环(硬件故障判定)
若烧录校验通过,但复位后只输出 boot:0x4 (DOWNLOAD) / waiting for download,应用从未启动,应先排查 BOOT 电平、USB 数据线、供电和接口焊接。更换已知正常线材与板卡对照,必要时用 USB-TTL 从 UART 验证;Flash 内容有效时不要把 ROM 下载模式误判为 Web 或 WiFi 固件故障。
登录接口间歇失败 / 并发请求返回 000(CPU 密集运算阻塞 lwIP)
登录压力测试期间若串口心跳正常,但 /api/health 也停止应答,说明认证计算可能阻塞网络任务。认证处理必须在受并发限制的工作任务中运行,并正确持有暂停后的请求对象;验收标准是登录期间 /api/health 持续可应答,超出并发预算时返回明确的 503,而不是连接被重置。
classic ESP32 浏览器套件中护栏 503 振荡或中途失联
出现成片 503 或 [WebGuard] ACTIVE/RECOVERED 反复切换时,记录 free8、blk8、持续时间和恢复速度,并对照当前 MemoryBudget.h 与 WebConfigManager.cpp,不要照搬旧版本阈值。秒级凹陷后自动恢复与持续下降是两类问题;只有后者才应触发功能降级或重启兜底。
classic ESP32 烧录后不自动运行应用(需串口 RTS 复位脉冲)
pio run -t upload 成功但应用未启动时,可先按板卡复位键,或用串口工具发送短 RTS 复位脉冲。复位后根据串口日志确认应用启动和 STA 状态;多次无效时重新上电并检查自动下载电路。
自动化调用 /api/mqtt/test 的暂存与恢复副作用
当前开发候选的POST /api/mqtt/test先校验新的恢复备份,再暂存测试MQTT节点并重建主客户端;connectionTestOnly隔离业务上报、订阅及连接动作。测试结果检测后尝试恢复原配置,存储故障或期间用户修改会保留“配置恢复待处理”,不能静默覆盖。该接口会写Flash、改变连接,不属于只读检查;调用前仍需保全配置和明确测试范围。结束后核对原配置、恢复标记及正式Broker连接,不能把“测试已连接”当作三者均通过。旧固件行为与当前候选区分,详见MQTT配置。不可达Broker应返回可理解的失败原因,不能把连接失败本身当作固件崩溃。
STA 在线但 Web/lwIP 挂起(串口心跳正常、TCP 全不通)
设备保持 STA 连接且串口心跳正常,但全部 HTTP 请求超时时,应优先定位 Web/lwIP 层而不是整机死机。复位前采集 [WebGuard]、[MEMGUARD] 和网络状态;现场可用串口复位或重新上电恢复。若能重复出现,必须作为发布阻塞问题处理并补充回归用例。
AP 回退后长时间驻留 AP 模式(探测退避属正常行为)
设备重启或 STA 失败后会回退 AP,并按 NetworkManager.h 定义的探测间隔和退避策略重试目标 SSID。串口持续出现 [WiFi-AP] Pre-scan / Probing WiFi 且目标 SSID 不可见时,保持 AP 属预期。测试期间不要连接设备 AP;确认路由器侧恢复后,观察 STA、mDNS 和 MQTT 是否自动恢复。
无 PSRAM 设备高负载后 API 持续 503
持续返回 503 "Server low memory, request rejected" 表示 Web 内存保护尚未解除。停止压力后观察 free8、blk8 和 memguard 等级是否恢复;若仍无恢复,先保留日志,再通过串口复位或重新上电。恢复后降低 soak 并发和轮询频率,并确认未使用功能已关闭;具体判定阈值以当前源码为准。
soak 零星超时集中在文件系统类端点(日志 rotate 同步写)
若超时集中在 /api/filesystem、/api/files、/api/logs*,同时重启计数和 heap 趋势正常,检查是否与 LittleFS 日志 flush/rotate 同步写重合。零星恢复不能直接忽略:报告中仍要记录失败率和端点分布;超过发布门槛时再评估异步写入。

