1、脚本工具概述:为什么嵌入式测试需要脚本化?脚本语言选型对比(Python vs TCL vs Shell)
1.1 嵌入式测试的痛点——我踩过的坑
做嵌入式测试十几年了,我见过太多团队还在用手工点来点去的方式测板子。说实话,这效率太低了。
我记得刚入行那会儿,带我的老工程师让我测一块电源管理芯片。一共48个寄存器,每个寄存器要写8种组合,再读回来验证。手工操作?一天测一个芯片都费劲。后来我实在受不了,花了两天写了个TCL脚本,十分钟跑完全部测试。老工程师看着屏幕刷刷刷滚过去的数据,愣了半天说:「你小子早该这么干。」
嵌入式测试为什么要脚本化?说白了就三个字:受不了。
- 重复劳动太多:同样的读写操作,同样的配置流程,同样的数据比对,一天重复几百次。是人就会出错,但脚本不会。
- 回归测试噩梦:改一行代码,全盘重测。手工测?你想想看,一个项目迭代十次,测试团队就得崩溃十次。
- 覆盖率根本没法保证:手工测试只能覆盖「正常路径」,边界条件、异常流程、压力场景,基本靠运气。
核心观点:脚本化不是锦上添花,而是嵌入式测试的刚需。没有脚本,你根本测不透一块现代SoC。
1.2 脚本化能解决什么问题?
我习惯把脚本在嵌入式测试中的作用分成四个层次。你可以对照看看自己团队到了哪一层。
| 层次 | 能力 | 典型场景 |
|---|---|---|
| L1 自动化执行 | 替代手工操作 | 寄存器读写、GPIO控制、固件烧录 |
| L2 数据驱动 | 参数化测试 | 不同电压/频率下的ADC精度测试 |
| L3 结果分析 | 自动比对与报告 | 波形比对、日志分析、性能统计 |
| L4 智能调度 | 动态决策与自适应 | 根据前一步结果调整测试策略 |
我在做一款车规级MCU的测试时,就吃过L1都没做到的亏。当时有个DMA传输的测试用例,手工操作需要配置源地址、目的地址、传输长度、触发源等十几个参数。测试工程师漏配了一个中断使能位,结果DMA传输完了没产生中断,整个测试流程卡死。后来我写了个脚本,把所有参数封装成函数,调用时只需传三个参数。嗯,从那以后,这种低级错误再也没出现过。
1.3 脚本语言选型对比:Python vs TCL vs Shell
选脚本语言这事,我见过太多争论了。有人非Python不用,有人抱着TCL不放,还有人觉得Shell天下第一。我的态度是:没有银弹,看场景。
下面这张表是我个人经验总结的,你可以当个参考。
| 维度 | Python | TCL | Shell |
|---|---|---|---|
| 学习曲线 | 平缓,语法优雅 | 中等,语法独特 | 简单,但易出错 |
| 硬件交互能力 | 强(pySerial, pyVISA, ctypes) | 强(原生支持socket, 串口) | 弱(依赖外部工具) |
| 数据处理 | 极强(numpy, pandas) | 一般(需自己实现) | 弱(awk/sed勉强能用) |
| 跨平台 | 优秀 | 优秀 | Linux/Unix为主 |
| 社区与生态 | 极其丰富 | 较窄(EDA领域为主) | 丰富但碎片化 |
| 典型应用场景 | 自动化测试框架、数据分析、GUI | 芯片验证、EDA工具集成 | 系统初始化、日志处理、简单监控 |
1.4 各语言实战场景分析
Python——我的主力语言
如果你只能学一门脚本语言,我建议你学Python。为什么?因为它的生态太强了。
举个例子,我要测一个通过串口通信的传感器模块。用Python,三行代码就能打开串口、发指令、收数据:
import serial
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
data = ser.write(b'AT+READ\r\n')
然后我想把采集到的1000组数据画成曲线看看有没有异常?加两行:
import matplotlib.pyplot as plt
plt.plot(raw_data)
plt.show()
这在TCL或Shell里,你得折腾半天。Python的pytest框架更是把测试用例管理、参数化、夹具、报告生成全包了。我在项目中用pytest写过一套自动化测试框架,覆盖了2000多个测试用例,跑一次全量回归只需要40分钟。手工测?至少两周。
我的建议:新项目首选Python。除非你有特殊约束(比如团队已有大量TCL积累,或者目标环境只有BusyBox)。
TCL——芯片验证的老炮
TCL这语言,说实话,语法有点反人类。但它在芯片验证领域就是霸主地位。为什么?因为EDA工具(比如Cadence、Synopsys的那些)原生支持TCL。
我曾经参与过一个FPGA验证项目,需要控制逻辑分析仪抓波形。EDA工具只暴露了TCL接口,没办法,硬着头皮学。学完之后发现,TCL在「控制外部工具」这件事上确实有两把刷子:
# 打开一个硬件调试会话
open_session -hardware localhost:3121
# 配置触发条件
add_trigger -signal "clk" -edge rising
# 开始采集
run_acquisition -time 100us
TCL的强项在于:它本身就是被设计用来做「工具胶水」的。你可以在TCL里调用系统命令、操作文件、控制硬件,而且几乎所有EDA工具都认它。但如果你要做复杂的数据分析或者写个漂亮的测试报告,TCL就力不从心了。
避坑指南:我曾经在一个项目里试图用TCL写一个复杂的测试调度器,结果代码越写越乱,最后不得不重写。TCL适合做「薄胶水层」,不适合做「厚业务逻辑」。如果你发现TCL脚本超过500行,就该考虑换Python了。
Shell——轻量级瑞士军刀
Shell脚本,说白了就是Linux命令的批处理。它的优势在于:零依赖。任何Linux系统都自带Shell,不需要装Python解释器,不需要装任何库。
我在做嵌入式Linux系统测试时,经常用Shell写一些「一次性」的测试脚本。比如检查系统启动后关键进程是否都在:
#!/bin/sh
for proc in sshd crond syslogd; do
if pgrep -x "$proc" > /dev/null; then
echo "$proc: OK"
else
echo "$proc: FAIL"
fi
done
或者监控CPU温度:
while true; do
cat /sys/class/thermal/thermal_zone0/temp
sleep 1
done
Shell的缺点也很明显:语法太糙,容易出错。变量引用忘了加引号?文件名里有空格?脚本直接炸。数组操作?蹩脚。浮点运算?基本别想。
我的习惯:Shell只用来做「系统级」的轻量任务,比如环境检查、日志轮转、简单监控。一旦涉及逻辑判断、数据处理、硬件交互,我立刻切到Python。
1.5 怎么选?我的决策框架
说了这么多,到底怎么选?我一般按这个思路来:
- 看目标环境:如果目标板子上只有BusyBox(比如一些极简的嵌入式Linux),那只能用Shell。如果板子上能跑Python(哪怕只是MicroPython),优先Python。
- 看交互对象:如果主要跟EDA工具打交道(比如做芯片验证),TCL是绕不开的。如果跟通用硬件(串口、网口、GPIO)交互,Python更顺手。
- 看团队积累:如果团队已经有大量TCL或Shell的测试库,别为了「技术时髦」强行换Python。兼容旧资产也是成本。
- 看复杂度:脚本超过200行?别用Shell。超过500行?别用TCL。老老实实上Python。
最后说一句:别纠结「哪个语言最好」,而是问「哪个语言最适合我当前的问题」。我见过有人用Python写了个三行就能搞定的Shell脚本,也见过有人用Shell硬写了上千行的测试框架。工具是为人服务的,别反过来。
下一章,我会带你手把手搭建一个基于Python的嵌入式测试框架。到时候你就知道,脚本化到底能省多少事了。