首页 > Python资料 博客日记
pytest+allure+excel实现python调CANoe进行诊断自动化测试(二)
2024-08-08 09:00:06Python资料围观78次
一、前言
本文主要介绍整体框架构成及python调CANoe COM接口封装的方法
二、测试框架的好处
当我们开发软件时,需要确保软件的各个部分能正常工作。为了做到这一点,我们需要测试软件,即检查软件是否按照我们预期的方式运行。传统的测试通常是手动的,即人工点击按钮、输入数据来模拟用户行为,来检查软件功能是否正常。但是这种方式效率低下且容易出错。
为了提高测试效率和质量,我们可以构建一个自动化测试框架。这个框架就像一个机器人,能自动执行测试用例,验证软件的功能是否正常。构建自动化测试框架的好处是可以节省时间和人力资源,并确保每次更新后软件依然正常运行。同时,自动化测试框架可以帮助我们更方便地合作,共享测试用例和结果,确保软件质量。因此,构建自动化测试框架可以帮助我们更快速、更准确地测试软件,确保软件质量。
主要好处分为以下几点:
1. 提高测试效率:自动化测试框架可以自动执行测试用例,省去了手动测试的时间和劳动成本。测试团队可以更快速地执行测试,并及时发现问题。
2. 提高测试覆盖率:自动化测试框架可以帮助测试团队更全面地覆盖功能、边界条件和各种场景,确保软件质量。
3. 降低测试成本:虽然构建自动化测试框架需要一定的投入,但长期来看,自动化测试可以减少重复劳动和人力资源成本。同时,自动化测试框架可以更快速地应对软件变更,减少因人为错误导致的质量问题。
4. 提高持续集成与交付软件的速度:自动化测试框架可以与持续集成工具(如 Jenkins)和持续交付流程结合,确保每次代码提交都能进行自动化测试,从而提高软件交付速度和质量。
5. 方便协作与回归测试:构建自动化测试框架可以使测试团队更容易共享测试用例和测试结果,方便团队合作。同时,自动化测试框架可以帮助团队更方便地进行回归测试,确保每次更新后软件依然符合预期。
三、框架构成
从上往下依次介绍:
allure-report
主要存放生成完的allure测试报告,之后执行结束后打开index.html即可查看完整的测试报告
comm
存放公用方法,因为是自动化测试框架嘛,后面后其他自动化测试要实现时需要用到的公用方法都在此处存放使用
canoe_application.py主要是python调CANoe的方法封装
execute_excel.py主要是读写excel的方法
security_key.py主要是进行安全解锁的方法
log
用于存放日志,目前只存放了CANoe生成的trace日志
report
存放allure生成的json文件。
Allure生成的.json文件是一种用于存储测试结果数据的格式化文件。通常,当运行测试并生成Allure测试报告时,Allure会生成.json文件来存储测试执行的详细信息,包括测试用例的执行结果、测试用例的状态、测试步骤的日志、附加信息等
里面的environment.properties是allure报告的配置文件
testcase
存放的是测试脚本。
testdata
存放测试数据。
根目录下的文件
config.ini:配置路径、设备等
environment.properties:测试报告环境配置,方便复制到allure生成的json文件中
main.py:执行文件
四、python调CANoe COM封装
canoe_application.py
import os
import time
from win32com.client import *
from pathlib import Path
class CANoe:
def __init__(self):
# self.application = None
self.application = DispatchEx("CANoe.Application")
self.ver = self.application.Version
print('Loaded CANoe version', self.ver.major, '.', self.ver.minor, '.', self.ver.Build, '...')
self.logging_collection = None
self.logger = None
self.log_target_dir = None
self.Measurement = self.application.Measurement.Running
def open_cfg(self, cfgname):
"""
打开工程
:param cfgname:
:return:
"""
if(self.application != None):
if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == '.cfg'):
self.application.Open(cfgname)
print("opening..."+cfgname)
else:
raise NameError("Can't find CANoe cfg file")
else:
raise RuntimeError("CANoe Application is missing, unable to open simulation")
def close_cfg(self):
"""
关闭工程
:return:
"""
if(self.application != None):
self.application.Quit()
self.application = None
def start_Measurement(self):
"""
运行
:return:
"""
retry = 0
retry_counter = 5 # 尝试5次
while not self.application.Measurement.Running and (retry < retry_counter):
self.application.Measurement.Start()
time.sleep(1)
retry += 1
if(retry == retry_counter):
raise RuntimeWarning("CANoe start measurement failed, Please Check Connection!")
def stop_Measurement(self):
"""
停止
:return:
"""
if self.application.Measurement.Running:
self.application.Measurement.Stop()
else:
pass
def send_Diag_Request(self, qualifier, stream_flag=False):
"""
发送诊断请求
:param qualifier: 限定符
:param stream_flag: 是否是给定的限定符
:return:
"""
data = qualifier
my_bytearray = bytearray.fromhex(data)
qualifier_list = list(my_bytearray)
self._diag_Request(qualifier_list, stream_flag)
# self.DiagDev = self.application.Networks("CAN").Devices("EPS").Diagnostic
# self.DiagReq = self.DiagDev.CreateRequest('0x10 0x01')
# self.DiagReq.Send()
# self.Diag.DiagStartTesterPresent()
def init_service(self, network, device):
"""
建立诊断服务
:param network: 网段
:param device: ECU qualifier
:return:
"""
time.sleep(10)
self.__gDiag = self.application.Networks(network).Devices(device).Diagnostic
# self.__gDiag.DiagStartTesterPresent()
def start_TesterPresent(self):
"""
开启诊断仪在线
:return:
"""
self.__gDiag.DiagStartTesterPresent()
def stop_TesterPresent(self):
"""
停止诊断仪在线
:return:
"""
self.__gDiag.DiagStopTesterPresent()
def _diag_Request(self, qualifier, stream_flag=False):
"""
执行服务
:param qualifier:
:param stream_flag: True以字节流形式发送,False根据具体限定符发送
:return:
"""
global diag_request
if stream_flag:
pass
else:
for a in qualifier:
print('%x' % a, end=' ')
if not stream_flag:
diag_request = self.__gDiag.CreateRequest(qualifier)
else:
diag_request = self.__gDiag.CreateRequestFromStream(bytearray(qualifier))
# else:
# diag_request = self.__gDiag.SetComplexParameter(bytearray(qualifier), iteration, subParameter)
diag_request.Send()
def check_Diag_Response(self):
return self._diag_Response()
def check_positive(self):
global diag_request
Res = ''
while diag_request.Pending:
time.sleep(1)
if diag_request.Responses.Count == 0:
Res = "NO RESPONSE"
else:
for k in range(1, diag_request.Responses.Count + 1):
diag_resp = diag_request.Responses(k)
stream = diag_resp.Stream
if diag_resp.Positive:
return True
else:
return False
def _diag_Response(self):
"""
诊断响应
:return:
"""
global diag_request
Res = ''
positive = True
while diag_request.Pending:
time.sleep(1)
if diag_request.Responses.Count == 0:
Res = "NO RESPONSE"
else:
for k in range(1, diag_request.Responses.Count + 1):
diag_resp = diag_request.Responses(k)
stream = diag_resp.Stream
if diag_resp.Positive:
positive = True
else:
positive = False
for i in stream:
Res = Res + '{:02X} '.format(i)
return Res, positive
def init_logging_collection(self):
"""
:return:
"""
self.logging_collection = self.application.Configuration.OnlineSetup.LoggingCollection
def select_logger(self, logger_number:int = None):
"""
:param logger_number:
:return:
"""
self.logger = self.logging_collection.Item(logger_number)
def set_log_target_dir(self, abs_path_to_dir = None):
"""
:param abs_path_to_dir: log存放位置
:return:
"""
path = Path(abs_path_to_dir)
if path.exists():
self.log_target_dir = path
else:
raise Exception("CANoe Wrapper: Log target directory does not exist")
def set_logfile_name(self, file_name:str = None):
"""
设置日志名字
:param file_name:
:return:
"""
file = Path(file_name)
if file.suffix == '.blf':
full_path = Path.joinpath(self.log_target_dir, file)
self.logger.fullName = str(full_path)
else:
raise Exception("CANoe Wrapper: Log target file has incorrect extension")
def start_logging(self):
"""
开始记录日志
:return:
"""
if self.logger is not None:
self.logger.Trigger.Start()
else:
raise Exception("CANoe Wrapper: No active logger was set")
def stop_logging(self):
"""
停止记录日志
:return:
"""
if self.logger is not None:
self.logger.Trigger.Stop()
else:
raise Exception("CANoe Wrapper: No active logger was set")
def get_logger_status(self):
"""
获取日志状态
:return: 返回TRUE 表示log状态为running,返回FALSE 表示log状态为stopped
"""
if self.logger is not None:
return str(self.logger.Trigger.Active)
def sleep(self, ms:int):
time.sleep(ms/1000)
if __name__ == '__main__':
app = CANoe()
app.open_cfg(r"D:\work\Partial_SDA\workspace\canoeworkspace\ECUTestwork.cfg")
time.sleep(1)
CANoe的COM接口在帮助文档中可以找到:
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj