
摘要:本文是 BSP 系列第 45 篇,聚焦 Regression Test(回归测试)。文章首先厘清 Build Test、Functional Test 与 Regression Test 的区别,指出 Regression 的本质是对历史已验证功能的持续重复验证;随后给出 BSP Regression 的 11 层测试树与"可重复"第一原则,强调 Test Case ID 与稳定结果追踪的重要性。接着深入探讨 Driver Regression 的测试维度、间接破坏的发现价值、Full vs Targeted Regression 的取舍,并给出公司 BSP 推荐的两级 Regression 流程(Fast + Full)。最后覆盖 Regression Matrix、失败信息规范、Regression History、Git Bisect 搭配、测试目录设计、Twister 与 HIL 集成,以及"测试金字塔"与 Host/Target 分层原则,帮助 BSP 从"能用"走向"可长期维护"。**BSP Regression Test**那么第 45 篇自然要解决一个更实际的问题:BSP 今天能跑,不代表下周还能跑。Regression Test 的任务,就是发现"以前能工作的东西,现在被改坏了"。一、Regression Test 到底是什么?先区分三个概念。Build Test代码 ↓ 编译 ↓ 成功?它只能回答:“这份代码现在能不能编译?”Functional Test例如 UART:UART Driver ↓uart_configure()↓uart_tx()↓ UART 输出测试:UART TX"hello"↓ 收到 hello ↓ PASS它回答:“这个功能现在能不能工作?”Regression TestRegression Test 问的是:“以前已经验证过的功能,在这次修改之后有没有被破坏?”例如:v1.2GPIO PASS UART PASS SPI PASS I2C PASS Timer PASS Interrupt PASS Boot PASS Flash PASS然后你修改了 Clock Driver。重新测试:Clock PASS GPIO FAIL ← 被间接破坏 UART FAIL SPI PASS I2C FAIL这就是 Regression。二、BSP Regression Test 的核心思想一个成熟 BSP 不应该只有:build.sh而应该逐渐形成:BSP │ ├── Build Tests │ ├── Unit Tests │ ├── Driver Tests │ ├── Integration Tests │ ├── Boot Tests │ ├── HIL Tests │ └── Regression Tests注意:Regression Test 不是某一种测试。它实际上是一个测试策略:已有测试集合 │ ↓ 每次代码变化重新执行 │ ↓ 比较结果 │ ↓ 发现 Regression所以可以理解成:Regression = 对历史上已经通过的测试进行持续重复验证。三、BSP Regression 最重要的测试层次我建议公司的 BSP 最终形成下面这棵树:BSP Regression │ ├──1.Build Regression │ ├──2.Devicetree Regression │ ├──3.Kconfig Regression │ ├──4.Driver Regression │ ├── GPIO │ ├── UART │ ├── SPI │ ├── I2C │ ├── Timer │ ├── PWM │ └── ADC │ ├──5.Interrupt Regression │ ├──6.Clock/Reset Regression │ ├──7.Boot Regression │ ├──8.Power/Sleep Regression │ ├──9.SMP/Multi-core Regression │ ├──10.HIL Regression │ └──11.Release Regression不是每个 SoC 都必须全部拥有。例如一个简单 Cortex-M4:GPIO UART SPI I2C Timer Interrupt Clock Boot Flash已经足够构成第一版 Regression Suite。四、第一原则:Regression Test 必须"可重复"这是 BSP Regression 最容易犯的错误。比如:UART test 打开串口工具 手工输入 hello 看看有没有输出这个叫:Manual Validation不是好的 Regression Test。因为 CI 无法可靠判断:PASS/FAIL真正的 Regression Test 应该:Flash firmware ↓ Reset ↓ Board boot ↓ Run test ↓ Generate machine-readable result ↓ PASS/FAIL例如:BOOT:PASS UART:PASS GPIO:PASS SPI:PASS I2C:PASS TIMER:PASS IRQ:PASS最终:REGRESSION: PASS五、Regression Test 最重要的设计:Test Case ID不要只写:test_uart test_gpio公司 BSP 应该给测试建立稳定 ID。例如:BSP-BOOT-001BSP-IRQ-001BSP-GPIO-001BSP-GPIO-002BSP-UART-001BSP-UART-002BSP-SPI-001BSP-I2C-001BSP-TIMER-001例如:BSP-UART-001Name:UART basic TX Board:company_board_a Peripheral:UART0 Expected:"HELLO_BSP"Timeout:2sec这样以后:v1.0v1.1v1.2v1.3都可以追踪:BSP-UART-001v1.0PASS v1.1PASS v1.2PASS v1.3FAIL这就开始具有真正的 Regression 能力了。六、Test Case 不应该只测试"Happy Path"例如 UART:最简单的是:UART TX但成熟 Regression 应该逐渐增加:UART │ ├── TX ├── RX ├── TX/RX ├── baudrate ├── parity ├── stop bits ├── FIFO ├── interrupt ├── timeout └── error handling例如:BSP-UART-001Basic TX BSP-UART-002Basic RX BSP-UART-003TX/RX loopback BSP-UART-004IRQ RX BSP-UART-005Different baudrate七、Driver Regression 应该测试什么?以 GPIO 为例。不要只测试:gpio_pin_set();而应该考虑:GPIO Regression │ ├── output high ├── output low ├── input ├── pull-up ├── pull-down ├── interrupt ├── rising edge ├── falling edge └── polarity测试关系:Devicetree │ ↓ GPIO Controller │ ↓ GPIO Driver │ ↓ Zephyr GPIO API │ ↓ Test Application这样才能发现:DT 改了 ↓ GPIO base address 错了 ↓ Driver 仍然编译成功 ↓ HIL Regression FAIL这类问题单纯 Build Test 根本抓不到。八、Regression 最有价值的地方:发现"间接破坏"这是 BSP Regression 最重要的价值之一。假设你修改:Clock Driver你可能只修改:drivers/clock_control/但是:Clock │ ├── UART ├── SPI ├── I2C ├── Timer └── PWM所以:Clock change ↓ UART frequency wrong ↓ UART test FAIL这就是:Regression Dependency因此 BSP 的 Regression Test 本质上是在保护:硬件依赖关系九、不要只测试"改动的 Driver"例如 Git diff:drivers/clock_control/company_clock.c错误思路:只跑 Clock Test更合理:Clock changed ↓ Run Clock tests ↓ Run dependent driver tests ↓ Run boot test ↓ Run smoke test也就是:Changed component ↓ Dependency graph ↓ Affected tests十、这就和前面的 Devicetree Dependency Graph 联系起来了我们之前讲过:UART │ ├── Clock ├── Pinmux └── IRQRegression 可以反过来利用这个关系:修改 Clock │ ├── UART ├── SPI ├── I2C └── Timer │ ↓ Regression所以未来成熟 BSP CI 可以做到:Git diff ↓ Changed files ↓ Affected drivers ↓ Affected tests ↓ Run targeted regression这叫:Test Impact Analysis十一、Full Regression vs Targeted Regression这两个一定要区分。Full Regression所有测试:1000tests全部执行。优点:覆盖全面缺点:时间长例如:30min1hour3hoursTargeted Regression假设修改:drivers/serial/那么:UART tests Boot tests Console tests 相关 HIL tests优先执行。例如:1000tests ↓ 分析影响 ↓120tests下面用一张表格从五个维度对比两者:维度Full RegressionTargeted Regression执行范围全部测试(如 1000 tests)仅受影响的相关测试(如 120 tests)