之前介绍过 Expect 作为处理程序交互工具的使用。
结合串口命令以及 Expect 读取输入输出,针对一些具有固定流程而且能通过输出判断命令执行情况的测试用例,可以实现基于串口的测试自动化。
在使用串口调试过程中,需要手动输入执行命令,交互性输入,以及等待执行结果。基本所有的信息都在 tty 中串行的进行显示。痛点有下面几个
- 重复命令手动输入执行
- 交互性输入
- 等待执行信息,不能自动保存到文件
- 串口调试环境本身edit 便利性
基于以上的问题,需要存在需求:
- 可以将执行命令存放脚本中,而且可以去调用执行
- 可处理交互性输入
- 对于执行命令输出可以保存到 log 文件
-
基于 SecureCRT
SecureCRT 脚本,使用 python 语言
优点:
- GUI 界面,操作直观
- python syntax 语法特性支持强大
缺点:
- SecureCRT 过重,本身安装麻烦
- 仍然需要基本交互,SecureCRT 内调用脚本
- 与 jenkins 的集成
-
基于 Terminal 环境
首先要解决的是串口环境,这里使用 picocom 命令行工具,类似的有 minicom 等。
其次,针对需要交互行输入,使用 Expect 处理,Expect 基于 TCL (Tool control language)
最后,得到的 .expect 脚本可以通过 Jenkins pipeline 进行调用。
优点:
- 轻量化,可通过命令行安装
- 所有过程都在 Terminal 操作
- 集成到 Jenkins,完全支持自动化流程
缺点:
##实际解决
针对上面两种方案,如果是非重复性调试,使用前者上手更快。
如果有需要多次重复性,或者自动化测试需求,选择后者。
下面给出使用 Expect 的一个 demo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#!/usr/bin/expect
# -d: debug mode
# expect config
set timeout 30
log_file test-expect.log
# picocom config
set baudrate "115200"
set device "/dev/ttyUSB0"
set prompt "=>"
# function define
set interval 5
set iter_cnt 10
proc start_xvr_debug { prompt } {
send "xvr_client_dbus\r"
expect $prompt
}
proc test_switch_channel_display { iter_cnt interval prompt } {
for { set i 1 } { $i < $iter_cnt } { incr i 1 } {
send "switch_channel_display -cam 0 -ch 0 -onoff 1\r"
expect $prompt
exec sleep $interval
send "switch_channel_display -cam 0 -ch 0 -onoff 0\r"
expect $prompt
exec sleep $interval
send "switch_channel_display -cam 0 -ch 1 -onoff 1\r"
expect $prompt
exec sleep $interval
send "switch_channel_display -cam 0 -ch 1 -onoff 0\r"
expect $prompt
exec sleep $interval
}
}
proc test_start_stop_pipeline { iter_cnt interval prompt } {
for { set i 1 } { $i < $iter_cnt } { incr i 1 } {
send "stop_pipeline /dev/xvr_pipeline-0\r"
expect $prompt
exec sleep $interval
send "stop_pipeline /dev/xvr_pipeline-1\r"
expect $prompt
exec sleep $interval
send "start_pipeline /dev/xvr_pipeline-0\r"
expect $prompt
exec sleep $interval
send "start_pipeline /dev/xvr_pipeline-1\r"
expect $prompt
exec sleep $interval
}
}
spawn picocom -b $baudrate $device
expect "Terminal ready\r"
send "\r"
# send "xvr_client_dbus\r"
# expect $prompt
start_xvr_debug $prompt
test_switch_channel_display $iter_cnt $interval $prompt
# test_start_stop_pipeline $iter_cnt $interval $prompt
expect eof
# interact
wait
|
在具体使用中遇到的有几个小坑:
- 集成到 jenkins 时,jenkins 用户无法获得
/dev/ttyUSB0
权限。
sudo
执行 Expect 脚本进程 kill
详情见尾注意小节。
-
关于 jenkins 用户无法获取 /dev/ttyUSB0
权限
在这里最好不要直接使用 sudo
,使用 root 权限执行的坏处在于,当你想要中断 expect 脚本时,也必须使用 root 权限。并且在集成到 Jenkins 时,jenkins 用户起了 root 权限的进程,在中断 job 的时候。expect 任然在 jenkins node 上继续执行。
解决的方案是将 jenkins 用户加入拥有 dev 设备权限的用户组。
1
|
sudo usermod aG dialout jenkins
|
-
sudo 执行的 expect 进程kill
sudo killall -u USER expect