副标题:板端仍是 C;电脑侧 50 到 80 行脚本跑回归,不是做网站
专栏:《嵌入式学生的方案测试课》第 14 篇(胶水)
前置:第 4 篇会手发 AT;第 12 篇理解要统计数字;第 13 篇厌倦手抄拷机表
标签:嵌入式、Python、串口、软件测试、自动化
读者:会一点 Python 语法,没写过带超时的串口脚本;JD 写了简易 PC 工具
学完交什么:脚本 + csv + README(COM 口和波特率)+ 10 次错密码统计
主实验:ESP8266。没有板可以用串口环回或只跑解析函数的单元测试,但要写明。
0. 这篇结束你能干什么
- 写 50 到 80 行脚本:打开串口,发
AT,判断OK/ERROR,有超时。 - 错密码连接 10 次,输出次数、每次耗时、ERROR 原文到 csv。
- 能说明:产品固件仍是 C;Python 在电脑上当手。不要和板子日志抢同一串口。
- 脚本判定条件写进缺陷单:「有回显」不等于成功,要看
ret/OK/FAIL。
嵌入式校招 JD 公开要求简易 PC 调试工具(控制台/对话框)。方案测试用脚本跑回归,不是做 Web。
1. 为什么手发 AT 不够,却也不能一上来上框架
手发:学习协议、写第一份会话。回归 10 次错密码、100 次重连、2 小时一行,手会作弊、会漏。
学生容易跳到 pytest 插件宇宙,或写一个带登录页的平台。岗位要的是:
- 发得对(新行、超时、编码)
- 收得全(不要读一行当成功)
- 判得严(关键字)
- 落得盘(csv,方便贴报告)
泰芯公开 WiFiTestTool 通过串口下 AT 做 SRRC 发包;AH 有 netat/netlog 网口工具。学生脚本是同类胶水的迷你版。不逆向官方工具,只学「串口下命令 + 用返回值判定」。
公开 SRRC 警告:改 gain 要先暂停发包;AT 返回失败才是失败。脚本如果把「串口有回显」当成校准成功,会制造假通过。
2. 最小原理
2.1 串口是字节流,不是函数调用
pyserial读到的是流。AT 以\r\n分行(第 4 篇新行模式)。你要:
- 写:命令 +
\r\n - 读:直到
OK/ERROR/FAIL或超时 - 超时:宁可判失败,不要死等
编码:先latin-1或按字节,避免日志里的中文/乱码把decode('utf-8')摔死。保存原文。
2.2 不要抢串口
同一 COM 口不能:你脚本开着,串口助手也开着。拷机日志如果要人工看,脚本把日志 tee 到文件,人看文件。
2.3 判定写清楚
| 现象 | 判定 |
|---|---|
| 收到独立一行 OK | AT 成功(对 AT 探活) |
| 收到 ERROR / FAIL / +CWJAP:x | 按用例:错密码可能是期望失败 |
| 超时 | 失败,记录已收部分 |
| 有乱七八糟回显但无 OK | 失败 |
| 板子复位横幅 | 单独事件,不是 OK |
错密码 10 次的「成功」定义是:每次都在超时前给出明确失败,且之后 AT 仍探活。不是「连上了」。
3. 参考脚本(约 70 行,读懂再改 COM)
把下面存成labs/week14/at_wrongpass.py。COM 口改成你的。
# at_wrongpass.py 教学脚本:错密码 10 次统计importcsvimporttimeimportargparseimportserialdefread_until(ser,tokens,timeout):"""读到 tokens 之一或超时。返回 (text, hit, elapsed)."""ser.timeout=0.2buf=b""t0=time.time()tokens_b=[t.encode("latin-1")fortintokens]whiletime.time()-t0<timeout:chunk=ser.read(256)ifchunk:buf+=chunkfori,tbinenumerate(tokens_b):iftbinbuf:text=buf.decode("latin-1",errors="replace")returntext,tokens[i],time.time()-t0# 无数据也继续等到 timeouttext=buf.decode("latin-1",errors="replace")returntext,None,time.time()-t0defat_cmd(ser,cmd,tokens=("OK","ERROR","FAIL"),timeout=5.0):ser.reset_input_buffer()ser.write((cmd+"\r\n").encode("latin-1"))returnread_until(ser,tokens,timeout)defmain():ap=argparse.ArgumentParser()ap.add_argument("--port",default="COM3")ap.add_argument("--baud",type=int,default=115200)ap.add_argument("--ssid",default="lab-ap-01")ap.add_argument("--badpass",default="wrong-password-xx")ap.add_argument("--n",type=int,default=10)ap.add_argument("--out",default="wrongpass.csv")args=ap.parse_args()ser=serial.Serial(args.port,args.baud,timeout=0.2)time.sleep(0.2)text,hit,dt=at_cmd(ser,"AT")ifhit!="OK":raiseSystemExit("AT probe failed: %r %r"%(hit,text))rows=[]foriinrange(1,args.n+1):cmd='AT+CWJAP="%s","%s"'%(args.ssid,args.badpass)text,hit,dt=at_cmd(ser,cmd,tokens=("FAIL","ERROR","OK","WIFI GOT IP"),timeout=15.0,)# 错密码期望 FAIL/ERROR,若 OK/GOT IP 则判异常成功expected_fail=hitin("FAIL","ERROR")probe_text,probe_hit,_=at_cmd(ser,"AT",timeout=3.0)rows.append({"i":i,"hit":hitor"TIMEOUT","seconds":"%.3f"%dt,"still_ok":probe_hit=="OK","expected_fail":expected_fail,"excerpt":text.replace("\r","\\r").replace("\n","\\n")[:200],})print(i,rows[-1]["hit"],rows[-1]["seconds"],"alive"ifrows[-1]["still_ok"]else"dead")withopen(args.out,"w",newline="",encoding="utf-8")asf:w=csv.DictWriter(f,fieldnames=list(rows[0].keys()))w.writeheader()w.writerows(rows)n_fail=sum(1forrinrowsifr["expected_fail"])n_alive=sum(1forrinrowsifr["still_ok"])print("expected_fail %d/%d, alive_after %d/%d, csv=%s"%(n_fail,args.n,n_alive,args.n,args.out))ser.close()if__name__=="__main__":main()依赖:pip install pyserial。README 写 Python 版本、COM、波特率、新行已经由脚本发\r\n。
可选作业:从AT+CWLAP文本里用正则抠 RSSI 数字,追加一列。抠不到就留空,不要编。
可选:用subprocess调iperf3 -c ...把最后一行 Mbps 解析进另一张 csv。解析失败当失败,不要用「进程返回 0」当吞吐合格。
4. 实验步骤
- 手发 AT 探活仍 OK(第 4 篇)。先关串口助手。
- 改
--port。跑--n 1看能否完整结束。 --n 10生成 csv。- 人工抽看第 1、第 10 次 excerpt 是否真是错密码失败。
- 若 10 次里出现
WIFI GOT IP:密码其实对了或 AP 开放,环境错,不是脚本胜利。 - 把 csv 贴进测试记录。缺陷只在:超时、死后不探活、偶发连上。
没有板:把read_until用假字节喂单元测试(io.BytesIO不够串口,可用自己写 FakeSer)。交测试代码同样及格,注明无硬件。
5. 缺陷单:脚本判定条件
标题:【工具】自动化把「串口有回显」当成 AT 成功,SRRC 发包实际 ret=-1 说明(教学):公开 SRRC/AT 文档以返回码为准。脚本必须匹配 OK/ERROR/ret=。 期望:ret=-1 记失败,不写校准通过 实际:脚本见任意字节就点绿灯 分层:测试工具,不是芯片你自己的脚本若超时当成功,同样提单打自己。
6. 泰芯对照
| 公开工具 | 学生迷你版 |
|---|---|
| WiFiTestTool 串口 AT 发包 | pyserial 发 AT |
| netat 网口 AT | 本篇不实现;知道网桥可以不插 UART |
| netlog 拉日志 | 脚本 tee 到文件 |
| 对话框/控制台小工具(嵌入式 JD) | 本篇控制台即可,对话框是加分不是主业 |
不反编译、不破解授权、不把官方 exe 当自己作品写进简历。
7. 30 秒口径
Python 在电脑上发 AT、收日志、写 csv,固件仍是 C。
脚本必须有超时,用 OK/ERROR/FAIL 判定,不把有回显当成功。
错密码 10 次我用来统计失败是否可观察、之后是否还活着。
不和串口助手抢同一 COM。
8. 作业
labs/week14/ README.md at_wrongpass.py wrongpass.csv requirements.txt # pyserialREADME 至少:COM、波特率、如何停、不要抢口、期望失败的定义。
Git 提交可以,但不要提交真实 SSID 密码。--ssid用实验名。
9. 自测题
- 为什么 decode utf-8 可能把日志读炸?
- 错密码用例里收到 OK 该高兴吗?
- 脚本和串口助手同时打开会怎样?
- 死等没有 timeout 的危害?
- 简历写精通 Django 对这个岗有帮助吗?
- iperf 返回码 0 能否当吞吐达标?
- 官方 WiFiTestTool 能否写进「我开发的工具」?
- 10 次统计的分母为什么重要?
10. 学生常见翻车
- 简历精通 Python Web。
- 脚本无 timeout。
- 抢串口。
- 把期望失败当成脚本 bug 反复改密码。
- csv 不提交只交「感觉 10 次都挂了」。
- 真密码进 Git。
11. 下一篇预告
第 15 篇:《先查供电、天线和传感器 CRC:方案测试怎么跟硬件同事对话》。
脚本再绿,天线没接也是红。下一篇松天线、拔传感器、波特率设错、劣质线供电,把锅从协议栈拿开。
附录 A. 自测题参考答案
- 非 UTF-8 字节抛异常,后面的 OK 再也读不到。
- 不高兴。错密码连上是安全/逻辑缺陷。
- 端口占用或各读走一半字节,判定随机。
- 拷机脚本卡死,假阳性过夜。
- 几乎没有。要串口和表格。
- 不能。要解析 Mbps 和丢失,对照需求。
- 不能。可写「使用过公开工具,理解串口 AT 发包」。
- 3/3 和 3/100 决策完全不同。
附录 B. 公开资料
- 嵌入式软件工程师 JD:PC 端控制台/对话框小工具
- Wi-Fi4 SRRC:WiFiTestTool 串口 AT;返回值
- AH:netat / netlog
- 第 4 篇新行与超时
(第 14 篇完)
12. README 最低限度(作业按此抄)
# at_wrongpass Python 3.x pip install pyserial 用法: python at_wrongpass.py --port COM5 --baud 115200 --ssid lab-ap-01 --badpass xx --n 10 前置:关闭串口助手;模组已 AT OK;实验 AP 存在 期望:10 次均为 FAIL/ERROR,之后仍 AT OK 不要:真实家庭密码;把 TIMEOUT 当通过 输出:wrongpass.csv13. 常见脚本病和对应缺陷
| 病 | 现象 | 修 |
|---|---|---|
没\r\n | 永远 timeout | 第 4 篇新行 |
| timeout 太短 | 正确连网被判失败 | CWJAP 用 15s,探活用 3s |
| 读一行就当结束 | 漏掉 FAIL 在后面 | 读到 token 或超时 |
| utf-8 decode | 异常退出 | latin-1 |
| 不 reset 输入缓冲 | 上次尾巴污染本次 | reset_input_buffer |
| 和助手抢口 | 随机 | 关助手 |
| 把 OK 当错密码成功 | 逻辑反了 | expected_fail |
第 14 篇脚本里WIFI GOT IP出现在错密码实验 = 立刻停,检查 SSID/密码是否其实对了,或 AP 开放。
14. 把 iperf 解析进 csv 的边界
subprocess.run(["iperf3","-c",ip,"-t","5"], capture_output=True, text=True)
然后找Mbits/sec。解析不到 = 失败,返回码 0 不够。
不要在脚本里写if bitrate > 10: pass除非需求签字。脚本负责记数,人负责对照需求。
15. 和官方工具的关系,简历一句
「使用串口 AT 做过回归统计脚本;了解原厂 WiFiTestTool/netat 是同类胶水。未逆向。」
不要:「开发了泰芯产线校准软件」。