python重启压力测试笔记通过继电器控制车机电源通断 需配合logger日志记录和relayControl使用继电器控制方法。
# coding:utf-8 """ author:yutao 函数功能描述:控制8路继电器中的3路开关GND/BAT/ACC电源通断,车机上电后检查串口关键词,判断设备安卓是否启动,车机上下电源重启压力试验 版本变更: yutao: 2021/10/13 "V1013.1759" 修改继电器控制方法,优化连接串口法 yutao: 2021/10/13 "V1013.1025" 修改继电器控制方法,增加ACC、BAT、GND 继电器控制通道便于后续切换继电器控制通道 yutao: 2021/10/11 "V1011.0830" 修改测试模式0:直接上下电重启,模式1:ACC-OFF模式2:ACC-OFF重启不休眠; 新增上电保持时间和下电保持时间,用于启动和等待指定时间ACC-OFF等待指定时间后重启 yutao: 2021/10/08 "V1008.1513" 修改检查车辆启动和休眠的判断方法,由检查检查adb devices 改为监控CR7串口 启动关键字是否出现 "get_dataFromAndroid_start" 以及CR7 串口打印是否停止。用于调查脚本无故自动退出的问题, 检查是否频繁adb devices导致程序崩溃。用于调查脚本无故自动退出的问题, 检查是否频繁adb devices导致程序崩溃。 """ import serial import os # 用于操作adb命令和文件夹操作等 import re # 用于正则匹配 import time import serial.tools.list_ports from datetime import datetime from logset import logger # 调用自建记录日志的方法 from RelayControl3 import relay # 定义了8路继电器控制方法 port_name_list = [] relay_port = "" CR7_port = "" relay = relay() def test_init(): """ 主要检查继电器串口和车机串口通信是否正常 """ logger.info("当前执行:************************** 初步检查的测试 **************************") logger.info("检查继电器串口通信") relay.ALL_OFF() relay.GND_ON() relay.BAT_ON() relay.ACC_ON() logger.info("车辆串口通信检查") start_stauts = check_CR7_android_start(120) return (start_stauts) def Test_setup(TestMode): """ 测试预处理方法主要用于控制继电器打开测试中常连接的供电线开关 """ relay.ALL_OFF() if TestMode == 0: relay.GND_ON() else:
relay.GND_ON()
relay.BAT_ON()
def Test_teardown(TestMode, TestResult):
""" 测试后处理方法,主要用于控制继电器关闭测试中保持常连接的供电线开关,以及检查测试结果给出相应提示 """
TestMode = int(TestMode)
if TestResult == "Pass":
if TestMode == 0:
relay.GND_OFF()
else:
relay.BAT_OFF()
relay.GND_OFF()
input("测试已完成,按任意键退出!!!")
logger.info("测试已完成,按任意键退出!!!")
else:
CurrentTime = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
logger.info("测试失败,异常出现大致时间点:%s"%CurrentTime)
input("测试失败,请确认后按任意键退出!!!")
logger.error("测试失败,请确认后按任意键退出!!!")
def mkdir_screenshoot():
""" 新建保存截图文件夹方法,主要用于判断当前路径是否存在指定的screenshort文件夹,若无则新建该文件夹 """
CurrentPath = os.getcwd()
CurrentTime = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
path = CurrentPath + ("\\screenshort")
path_x = CurrentPath + ("\\screenshort\\%s"%CurrentTime)
if not os.path.exists(path):
os.mkdir(path)
if not os.path.exists(path_x):
os.mkdir(path_x)
return(path_x)
def power_on(TestMode):
""" 上电操作方法,主要用于根据测试模式,执行打开相应的继电器开关实现上电操作 """
# global relay_port
TestMode = int(TestMode)
if TestMode == 0:
relay.BAT_ON()
relay.ACC_ON()
else:
relay.ACC_ON()
def power_off(TestMode):
""" 下电操作方法,主要用于根据测试模式,执行打开相应的继电器开关实现下电操作 """
TestMode = int(TestMode)
if TestMode == 0:
relay.ACC_OFF()
relay.BAT_OFF()
else:
relay.ACC_OFF()
def check_CR7_android_start(WaitTime):
""" 检查车机安卓系统是否启动方法,主要通过检查车机串口打印的日志,正则匹配关键字,判断车机安卓系统是否正常启动方法 """
global CR7_port
CR7_serial = serial.Serial(CR7_port, 115200)
if not CR7_serial.isOpen():
CR7_serial.Open() # 若串口未打开,则打开串口连接
start_time = time.time()
for i in range(WaitTime):
time.sleep(1)
count = CR7_serial.inWaiting() # 获取串口缓存区数据
rec_str = CR7_serial.read(count) # 读取串口数据
logger.debug(rec_str)
""" 串口读取的日志无法直接进行正则匹配查询,需要进行一下解码,使用.decode()方法,默认UTF-8 车机串口打印的刚上电时的日志前20个位字符解码时容易报错,安卓启动关键字不会出现在上电瞬间,所以此处做切割 """
rec_str1 = rec_str[20:].decode()
if rec_str:
# 使用正则 re.findall()方法,查找日志中所有匹配的字符串,若匹配到关键字则证明车机安卓系统正常启动
chk_android_start = re.findall(r"get_dataFromAndroid_start", rec_str1)
if chk_android_start:
android_start_time = time.time()
logger.info("检查:车机启动成功,设备上电进入安卓系统启动警告页耗时:%d 秒"%(android_start_time - start_time))
break
CR7_serial.close()
if chk_android_start:
result = "Pass"
else:
result = "Fail"
logger.error("检查:设备安卓系统没有在 %d 秒时间内正常启动"%WaitTime)
return(result)
def check_adb(WaitTime):
""" 检查车机安卓系统是否启动方法,主要adb devices命令通过检查车机adb 是否在线,判断车机安卓系统是否启动 因执行测试过程中经常无故退出程序,无法排除是否频繁查询adb引起,暂时弃用 """
for j in range(WaitTime):
try:
adb_chk = os.popen("adb devices").read()
dev = adb_chk.splitlines()[1] # 获取adb decices 查询结果的第二行字符
if dev:
return(dev)
break
except Exception as e:
logger.error(e)
time.sleep(1)
def Wait_adb_disconnect(WaitTime):
""" 检查车机安卓系统是否休眠方法,主要adb devices命令通过检查车机adb 是否在线,判断车机安卓系统是否休眠 因执行测试过程中经常无故退出程序,无法排除是否频繁查询adb引起,暂时弃用 """
start_time = time.time()
for i in range(WaitTime):
adb_chk = os.popen("adb devices").read()
dev = adb_chk.splitlines()[1] # 获取adb decices 查询结果的第二行字符
if not dev:
end_time = time.time()
logger.info("设备ACC OFF %d 秒后进入休眠" %(end_time - start_time))
break
else:
time.sleep(1)
if dev:
result = "Fail"
logger.error("设备未在指定 %d 秒时间内休眠:" %WaitTime)
else:
result = "Pass"
return(result)
def Wait_CR7log_stop(WaitTime):
""" 检查车机安卓系统是否休眠方法,主要通过检查车机串口是否停止打印日志,判断车机安卓系统是否正常休眠 """
global CR7_port
chk_count = 0
CR7_serial = serial.Serial(CR7_port, 115200)
if not CR7_serial.isOpen():
CR7_serial.Open()
start_time = time.time()
for i in range(WaitTime+3):
time.sleep(1)
count = CR7_serial.inWaiting()
rec_str = CR7_serial.read(count)
logger.debug(rec_str)
if not rec_str:
chk_count += 1
else:
chk_count = 0
if chk_count == 3:
end_time = time.time()
logger.info("检查:车机ACC OFF后进入休眠耗时 %d 秒" %(end_time - start_time - 3))
break
CR7_serial.close()
if rec_str:
result = "Fail"
logger.error("检查:车机未在指定 %d 秒时间内休眠:" %WaitTime)
else:
result = "Pass"
return(result)
def Wait_start(WaitTime, KeepPowerON):
""" 封装的等待车机启动方法,主要实现检查车机是否启动成功,若成功则等待上电保持时间超时,否则返回启动失败状态 """
logger.info("等待系统启动 [安卓系统启动时间不能超过 %d 秒]。。。" %WaitTime)
start_time = time.time()
result = check_CR7_android_start(WaitTime)
end_time = time.time()
if result == "Pass":
logger.info("上电保持时间共 %d 秒,当前剩余等待时间 %d 秒" %(KeepPowerON, KeepPowerON - (end_time - start_time)))
time.sleep(KeepPowerON - (end_time - start_time))
return(result)
def Wait_sleep(TestMode, WaitTime, KeepPowerOFF):
""" 封装的等待车机休眠方法,主要实现检查车机是否休眠成功,并等待下电保持时间超时,否则返回休眠失败状态 """
TestMode = int(TestMode)
if TestMode == 1:
logger.info("ACC OFF 等待车机休眠 ,进入休眠时间不能超过 %d 秒"%WaitTime)
start_time = time.time()
result = Wait_CR7log_stop(WaitTime)
end_time = time.time()
if result == "Pass":
logger.info("下电保持时间共 %d 秒,当前剩余等待时间 %d 秒" %(KeepPowerOFF, KeepPowerOFF - (end_time - start_time)))
time.sleep(KeepPowerOFF - (end_time - start_time))
else:
logger.info("等待 %d 秒下电保持时间" %KeepPowerOFF)
time.sleep(KeepPowerOFF)
result = "Pass"
return(result)
def get_screencap(PicID, path):
""" 获取车机安卓界面截屏并保存到指定路径的方法,暂时弃用 """
CurrentTime = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
try:
os.system("adb shell screencap /data/test_%d_%s.png" %(PicID, CurrentTime))
os.system("adb pull /data/test_%d_%s.png %s"%(PicID, CurrentTime, path))
logger.info("安卓界面截图成功,图片名称:test_%d_%s.png" %(PicID, CurrentTime))
os.system("adb shell rm /data/*.png")
except Exception as e:
logger.error(e)
def TestProcess(TestMode, TestTimes, WaitStart, KeepPowerON, WaitSleep, KeepPowerOFF):
""" 测试过程方法,封装具体执行的测试步骤 """
Test_setup(TestMode)
# path = mkdir_screenshoot() #暂时弃用
for i in range(TestTimes):
logger.info("当前执行:************************** 第 %d 轮测试 **************************"%(i+1))
logger.info("连接电源,上电开机:")
power_on(TestMode)
Start_status = Wait_start(WaitStart, KeepPowerON)
if Start_status == "Fail":
result = "Fail"
break
logger.info("断开电源,下电关机:")
power_off(TestMode)
# 下电等待时间
sleep_status = Wait_sleep(TestMode, WaitSleep, KeepPowerOFF)
if sleep_status =="Fail":
result = "Fail"
break
logger.info("检查:本轮测试已完成,测试结果:PASS")
# 判断测试次数是否到底要求
if i+1 == TestTimes:
result = "Pass"
break
Test_teardown(TestMode, result)
def TestPreStart():
ScriptVersion = "V1013.1759" # 当前测试脚本版本,手动修改
UserName = os.getlogin() # 当前电脑登录的账号
CurrentTime = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
logger.info("*******************************MMI车机上下电重启压力测试*******************************")
logger.info("当前测试脚本版本: %s" %ScriptVersion)
logger.info("测试人员:%s" %UserName)
logger.info("测试启动时间:%s" %CurrentTime)
def TestStart(mode, testmode):
""" 测试启动方法,封装测试参数配置,测试模式、上/下电保持时间、压测次数等,及启动执行测试过程。 """
# get_portlist()
global relay_port
global CR7_port
if testmode not in mode:
input("测试模式选择错误,请确认后,重新启动脚本并输入正确模式!!!")
logger.error("测试模式选择错误,请确认后,重新启动脚本并输入正确模式!!!")
else:
WaitStart = int(input("请输入等待启动超时时间[s/秒]: "))
KeepPowerON = int(input("请输入上电保持时间(不少于等待启动超时时间)[s/秒]: "))
if testmode == 1:
WaitSleep = int(input("请输入下电后,等待休眠超时时间[s/秒]: "))
else:
WaitSleep = 0
KeepPowerOFF = int(input("请输入下电保持时间(不少于等待休眠超时时间)[s/秒]: "))
TestTimes = int(input("请输入需要压测的次数:"))
# ScreenCap = int(input("是否需要保存屏幕截图[0:不保存,1:保存]:"))
relay_port = "COM"+input("请输入继电器串口号,数字即可[如COM3 输入:3]:")
CR7_port = "COM"+input("请输入车机设备串口号,数字即可[如COM3 输入:3]:")
relay.port = relay_port
relay.connect()
logger.info("参数配置:测试模式:%d [模式0:直接上下电重启,模式1:ACC-OFF休眠重启,模式2:ACC-OFF不休眠重启]"%TestMode)
logger.info("参数配置:等待启动超时时间:%d 秒" %WaitStart)
logger.info("参数配置:上电保持时间:%d 秒" %KeepPowerON)
logger.info("参数配置:等待休眠超时时间: %d 秒" %WaitSleep)
logger.info("参数配置:下电保持时间:%d 秒" %KeepPowerOFF)
logger.info("参数配置:压测次数:%d " %TestTimes)
check_init = test_init()
if check_init == "Pass":
TestProcess(TestMode, TestTimes, WaitStart, KeepPowerON, WaitSleep, KeepPowerOFF)
else:
input("设备安卓进程没有正常启动,初始化失败,请检测后退出并重试!!!")
logger.error("设备安卓进程没有正常启动,初始化失败,请检测后退出并重试!!!")
relay.disconnect()
if __name__ == "__main__":
TestPreStart()
mode = [0, 1, 2]
TestMode = int(input("选择测试模式[模式0:直接上下电重启,模式1:ACC-OFF休眠重启,模式2:ACC-OFF不休眠重启]: "))
TestStart(mode, TestMode)