☰
Zephyr BSP: 45-BSP Regression Test
2026/9/29 3:38:36 网站建设 项目流程

摘要:本文是 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 Test
Regression 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 └── IRQ

Regression 可以反过来利用这个关系:

修改 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

全部执行。
优点:

覆盖全面

缺点:

时间长

例如:

30min1hour3hours

Targeted Regression

假设修改:

drivers/serial/

那么:

UART tests Boot tests Console tests 相关 HIL tests

优先执行。
例如:

1000tests ↓ 分析影响 ↓120tests

下面用一张表格从五个维度对比两者:

维度Full RegressionTargeted Regression
执行范围全部测试(如 1000 tests)仅受影响的相关测试(如 120 tests)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询