Python3 pexpect自动化测试

Python3 pexpect自动化测试

1. pexpect简介

1.1 pexpect超时异常/程序结束

    不将pexpect.EOF、pexpect.TIMEOUT加入pexpect列表时,在程序运行结束或者pexpect超时的情况下,将抛出异常,可以使用"try ... except ..."来捕获处理异常,但是这改变了程序的正常执行流程,因此建议在使用pexpect的时候将pexpect.EOF、pexpect.TIMEOUT加入pexpect列表,使程序的执行流程可控,同时也可以直接使用pexpect的返回值做相应的处理。

1.2 pexpect timeout参数设置

    pexpect等待程序timeout应根据命令实际执行时间来确定,以避免不必要的等待时间;例如,某条命令执行仅需1秒,则可设置timeout = 3,给程序足够的执行时间,又能避免不必要的等待。

2. AARCH64服务器reboot

2.1 reboot过程介绍

    AARCH64服务器reboot之后将从固化在单板Flash存储器中的UEFI启动,由UEFI来引导grub内核启动,再由grub引导linux内核启动;
如下图所示,UEFI将提示用户“Press Enter to boot OS immediately.”、“Press any other key in 10 seconds to stop automatical booting...”。

Python3 pexpect自动化测试_第1张图片

2.2 Python脚本分析

     uefi reboot到打印"Press any other key in 10 seconds to stop automatical booting"时间不确定,通常情况下不会任何异常,因此此次采用pexpect默认timeout参数,用while循环等待“Press any other key in 10 seconds to stop automatical booting”,关键代码如下:

#!/usr/bin/python3
import os
import pexpect
import time



os.system('ipmitool -H %s -I lanplus -U root -P %s chassis power reset' % (ip, password))
child = pexpect.spawn('ipmitool -H %s -I lanplus -U root -P %s sol activate' % (ip, password))

index = child.expect(['Press any other key in .* seconds to stop automatical booting', pexpect.EOF, pexpect.TIMEOUT])
while (index != 0):
 index = child.expect(['Press any other key in .* seconds to stop automatical booting', pexpect.EOF, pexpect.TIMEOUT])
child.sendline("")

3. 进入uefi手动设置界面

3.1 uefi设置界面如下

Python3 pexpect自动化测试_第2张图片

Python3 pexpect自动化测试_第3张图片

3.2 思路分析

    此界面菜单顺序基本是固定的,可以通过按指定次数方向键高亮目标菜单,然而这种做法写出的脚本在不了解背景的情况下,没法看懂脚本用意,其次扩展性、可维护性不好,万一菜单有所增减或顺序调整,则脚本必须随之修改;

    我们是通过ipmitool及xshell连接到arm64服务器串口,因此图3.1所示应该是字符界面;目前我们从图中可以看到,高亮菜单字体颜色及背景与其他非高亮菜单不一致,因此我们只要能expect字符串、字体颜色、背景即可定位到目标菜单,由此我们可以联想到echo控制字符,最后我们只需要获取到uefi菜单控制字符就可以了;

   首先我们手动进入到3.1 uefi界面,写一测试脚本循环遍历一遍所有菜单,timeout时,打印缓存内容,从中分析获取我们需要的控制字符,脚本示例如下:

#!/usr/bin/python3
import pexpect

child = pexpect.spawn('ipmitool -H %s -I lanplus -U root -P %s sol activate' % (ip, password))

i = 0
while (i < 8):
 child.sendline("v")
 child.expect(['Any string', pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
 print(child.before)
 i = i + 1

    获取到执行结果,然后再shell终端ecoh-e "..."解析控制字符串,查看执行结果,获取菜单高亮对应的字符串(去掉不必要的坐标转义字符)。

 

3.3 python脚本

(高亮Boot Manager菜单并进入,注意:\\x1b这类字符主要为字体颜色、背景等转义字符,以及及特殊字符转义,避免与正则表达式冲突)

#!/usr/bin/python3
import pexpect

child = pexpect.spawn('ipmitool -H %s -I lanplus -U root -P %s sol activate' % (ip, password))

Boot_Manager = 'Boot Manager'
index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m'% (Boot_Manager), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
while (index != 0):
        child.sendline("v")
        index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m' % (Boot_Manager), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)


child.sendline('\r\n')

4. 启动设备选择

4.1 启动设备菜单界面

Python3 pexpect自动化测试_第4张图片

Python3 pexpect自动化测试_第5张图片

4.2 思路分析

    菜单选择与3.2是一样的原理,4.1图示中的菜单"EFI Network"、"EFI Network 1"、"EFI Network 2"、"EFI Network 3"有包含关系,高亮"EFI Network"需要注意,正则表达式不能使用"EFI Network.*",因为这会匹配到"EFI Network 2"等,需要使用更加精确的正则表达式,当然也可以将"EFI Network1"等添加到"EFI Network"之前,例如:child.expect(['EFI Network 1', 'EFI Network 2', 'EFI Network 3', 'EFI Network', pexpect.EOF, pexpect.TIMEOUT], timeout = 1)

4.3 EFI Network 2脚本示例

#!/usr/bin/python3
import pexpect



child = pexpect.spawn('ipmitool -H %s -I lanplus -U root -P %s sol activate' % (ip, password))

efinetwork2 = 'EFI Network 2'
index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m.*' % (efinetwork2), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
while (index != 0):
 child.sendline("v")
 index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m.*' % (efinetwork2), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)

child.sendline('\r\n')

5. 进入grub

5.1 grub界面

Python3 pexpect自动化测试_第6张图片

Python3 pexpect自动化测试_第7张图片

5.2 grub菜单选择界面脚本

(获取菜单高亮控制字符串等请参考3.2、4.2)

#!/usr/bin/python3
import pexpect

child = pexpect.spawn('ipmitool -H %s -I lanplus -U root -P %s sol activate' % (ip, password))

startup = 'Startup Estuary'
child.expect('Press .* to edit the selected item')
index = child.expect(['\\x1b\[30m\\x1b\[47m.*%s.*\\x1b\[0m\\x1b\[37m' % (startup), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
while (index != 0):
 child.sendline('v')
 index = child.expect(['\\x1b\[30m\\x1b\[47m.*%s.*\\x1b\[0m\\x1b\[37m' % (startup), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)

child.sendline('\r\n')

6. 启动linux

Python3 pexpect自动化测试_第8张图片

7. 完整Python脚本示例

#!/usr/bin/python3
import os
import pexpect
import time

ip = '192.168.1.101'
password = 'pass'

'''
/* -------------------------------------------------------------
 * reboot target device and connect to target by ipmitool
 * ------------------------------------------------------------- */
'''
os.system('ipmitool -H %s -I lanplus -U root -P %s sol deactivate' % (ip, password))
os.system('ipmitool -H %s -I lanplus -U root -P %s chassis power reset' % (ip, password))
child = pexpect.spawn('ipmitool -H %s -I lanplus -U root -P %s sol activate' % (ip, password))

'''
/* -------------------------------------------------------------
 * wait "Press any other key in .* seconds to stop automatical booting", enter to uefi
 * ------------------------------------------------------------- */
'''
index = child.expect(['Press any other key in .* seconds to stop automatical booting', pexpect.EOF, pexpect.TIMEOUT])
while (index != 0):
 index = child.expect(['Press any other key in .* seconds to stop automatical booting', pexpect.EOF, pexpect.TIMEOUT])
child.sendline("")

'''
/* -------------------------------------------------------------
 * enter into Boot Manager
 * menu entry: Boot Manager、Device Manager、Boot Maintenance Manager
 * ------------------------------------------------------------- */
'''
Boot_Manager = 'Boot Manager'
index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m' % (Boot_Manager), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
while (index != 0):
        child.sendline("v")
        index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m' % (Boot_Manager), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)

time.sleep(1)
child.sendline('\r\n')

'''
/* -------------------------------------------------------------
 * enter to Boot Manager -> EFI Network 2
 * ------------------------------------------------------------- */
'''
efinetwork2 = 'EFI Network 2'
index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m.*' % (efinetwork2), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
while (index != 0):
 child.sendline("v")
 index = child.expect(['\\x1b\[0m\\x1b\[37m\\x1b\[40m.*%s\\x1b\[0m\\x1b\[30m\\x1b\[47m.*' % (efinetwork2), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)

child.sendline('\r\n')

'''
/* -------------------------------------------------------------
 * select and enter to grub entry "Startup Estuary"
 * ------------------------------------------------------------- */
'''
startup = 'Startup Estuary'
child.expect('Press .* to edit the selected item')
index = child.expect(['\\x1b\[30m\\x1b\[47m.*%s.*\\x1b\[0m\\x1b\[37m' % (startup), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)
while (index != 0):
 child.sendline('v')
 index = child.expect(['\\x1b\[30m\\x1b\[47m.*%s.*\\x1b\[0m\\x1b\[37m' % (startup), pexpect.EOF, pexpect.TIMEOUT], timeout = 1)

child.sendline('\r\n')
child.interact()

 

 



你可能感兴趣的:(Python,Python3,pexpect自动化测试)