CANoe学习之通过Python自动控制CANoe工程中的CAPL Test Module测试节点进行测试
参考文献
1-https://mp.weixin.qq.com/s?__biz=MzIwMDgzOTg3Mg==&mid=2247485368&idx=1&sn=fed547154fadc5fc8239f1029e811021&chksm=96f64017a181c901b51a5f5c0a82f45faba14d8a7353f7f673a3935be3269e4361064fe1de06&mpshare=1&scene=1&srcid=07275TD9hE0AG6Sv6NsS4DLH&sharer_sharetime=1640049404966&sharer_shareid=52df95daab17081c7595d8cc4731d29f&exportkey=A60SVSc9LAgF1x12UlWo8Ic%3D&pass_ticket=MhTtat3pZzYUDZ3Dtg1zUGkVI4A%2FxU8KpQaxAnYtdxsmeTJEU23zcAHzvIGqJgsD&wx_header=0#rd
2-CANoe自带Demo: C:UsersPublicdocumentsVectorCANoeSample Configurations 12.0.189ProgrammingPython
代码内容及解释
# ----------------------------------------------------------------------------- # Example: Test Feature Set via Python # # This sample demonstrates how to start the test modules and test # configurations via COM API using a Python script. # The script uses the included PythonBasicEmpty.cfg configuration but is # working also with any other CANoe configuration containing test modules # and test configurations. # # Limitations: # - only the first test environment is supported. If the configuration # contains more than one test environment, the other test environments # are ignored # - the script does not wait for test reports to be finished. If the test # reports are enabled, they may run in the background after the test is # finished # ----------------------------------------------------------------------------- # Copyright (c) 2017 by Vector Informatik GmbH. All rights reserved. # ----------------------------------------------------------------------------- import time, os, msvcrt #导入时间、 *** 纵系统、输入输出库 from win32com.client import * #导入win32com.client所有模块,Com组件调用 from win32com.client.connect import * #导入win32com.client.connect所有模块,Com组件调用 from datetime import datetime #导入时间计算模块 # ------------------------------------------------------------------------------- # 主线程挂起,等待CANoe测试执行完毕(注:这里用到了pythoncom库里的API - PumpWaitingMessages),测试界面中d出CANoe相关运行消息。 # 线程等待处理,若条件为假(cond = False),则程序一直等待挂起,若条件为真(cond = True),则程序跳出 # ------------------------------------------------------------------------------- def DoEvents(): pythoncom.PumpWaitingMessages() #在当前线程下d出所有等待消息 time.sleep(.1) #延时0.1秒,线程挂起 def DoEventsUntil(cond): while not cond(): DoEvents() # ------------------------------------------------------------------------------- # 定义CANoe应用 # ------------------------------------------------------------------------------- class CanoeSync(object): """Wrapper class for CANoe Application object""" #定义类变量 Started = False Stopped = False ConfigPath = "" # ------------------------------------------------------------------------------- # 构造方法,Self代表类的示例 # ------------------------------------------------------------------------------- def __init__(self): app = DispatchEx('CANoe.Application') #创建CANoe应用对象实例 app.Configuration.Modified = False #CANoe 工程加载或者新建时不能被修改 ver = app.Version #CANoe 版本 print('Loaded CANoe version ', ver.major, '.', ver.minor, '.', ver.Build, '...', sep='') self.App = app self.Measurement = app.Measurement # 获取CANoe的测量配置 self.Running = lambda : self.Measurement.Running # 获取CANoe的运行状态 self.WaitForStart = lambda: DoEventsUntil(lambda: CanoeSync.Started) # 等待CANoe启动 self.WaitForStop = lambda: DoEventsUntil(lambda: CanoeSync.Stopped) # 等待CANoe停止 WithEvents(self.App.Measurement, CanoeMeasurementEvents) # 等待Measurement事件 # ------------------------------------------------------------------------------- # 加载CANoe工程,cfgPath-相对路径 # ------------------------------------------------------------------------------- def Load(self, cfgPath): # current dir must point to the script file cfg = os.path.join(os.curdir, cfgPath) #结合当前工程根目录os.curdir和给定子目录cfgPath cfg = os.path.abspath(cfg) #获取CANoe工程绝对路径 print('Opening: ', cfg) self.ConfigPath = os.path.dirname(cfg) #返回CANoe工程的路径名称 self.Configuration = self.App.Configuration #定义CANoe仿真配置 self.App.Open(cfg) #打开CANoe工程 # ------------------------------------------------------------------------------- # 加载Test Module测试配置:对象搜索路径:App – Configuration –TestSetup – TestEnvironments – Add() # ------------------------------------------------------------------------------- def LoadTestSetup(self, testsetup): self.TestSetup = self.App.Configuration.TestSetup #返回测试配置 path = os.path.join(self.ConfigPath, testsetup) #路径整合,返回testsetup路径 print("testenv path = ",path) time.sleep(3) testenv = self.TestSetup.TestEnvironments.Add(path) #把.tse测量环境Test Environment加入testsetup(注意:工程打开的时候该tse文件不在Test Modules里面) testenv = CastTo(testenv, "ITestEnvironment2") #ITestEnvironment2属于Vector自定义强制类型 print("testenv Name = ",testenv.Name) print("Sub Folders Count= ",testenv.Folders.Count) # TestModules property to access the test modules self.TestModules = [] #创建TestModule列表 self.TraverseTestItem(testenv, lambda tm: self.TestModules.append(CanoeTestModule(tm))) #Test Module添加到tse中,List末尾添加新对象 # ------------------------------------------------------------------------------- # 加载Test Unit(基于vTESTstudio生成),对象搜索路径:App – Configuration –TestConfigurations - Add() # ------------------------------------------------------------------------------- def LoadTestConfiguration(self, testcfgname, testunits): """ Adds a test configuration and initialize it with a list of existing test units """ tc = self.App.Configuration.TestConfigurations.Add() #添加Test Configurations到canoe工程 tc.Name = testcfgname #Test Configurations名称 print("testcfgname= ",testcfgname) tus = CastTo(tc.TestUnits, "ITestUnits2") #ITestUnits2属于Vector自定义强制类型 for tu in testunits: #遍历所有Test Units,加入到Test Configurations tus.Add(tu) print("Test Unit Name= ",tu) # TestConfigs property to access the test configuration self.TestConfigs = [CanoeTestConfiguration(tc)] # ------------------------------------------------------------------------------- # 启动CANoe工程,调用Measurement对象的Start方法 # ------------------------------------------------------------------------------- def Start(self): if not self.Running(): #若CANoe未启动 self.Measurement.Start() #则启动CANoe self.WaitForStart() #等待CANoe启动,d出相关信息 def Stop(self): if self.Running(): #若CANoe启动 self.Measurement.Stop() #则停止CANoe self.WaitForStop() #等待CANoe停止,d出相关信息 # ------------------------------------------------------------------------------- # 启动测试节点,调用TestModule对象的Start方法 # ------------------------------------------------------------------------------- def RunTestModules(self): """ starts all test modules and waits for all of them to finish""" # start all test modules for tm in self.TestModules: tm.Start() # wait for test modules to stop while not all([not tm.Enabled or tm.IsDone() for tm in app.TestModules]): #若当前CANoe工程中的所有TestModules在运行中或未激活,则程序等待 DoEvents() # ------------------------------------------------------------------------------- # 启动测试单元,调用TestConfiguration对象的Start方法 # ------------------------------------------------------------------------------- def RunTestConfigs(self): """ starts all test configurations and waits for all of them to finish""" # start all test configurations for tc in self.TestConfigs: tc.Start() # wait for test modules to stop while not all([not tc.Enabled or tc.IsDone() for tc in app.TestConfigs]):#若当前CANoe工程中的所有TestModules在运行中或未激活,则程序等待 DoEvents() # ------------------------------------------------------------------------------- # 循环遍历tse里面的Test Module和子文件 # ------------------------------------------------------------------------------- def TraverseTestItem(self, parent, testf): for test in parent.TestModules: #遍历tse里面的Test Module testf(test) #添加到Test Module集合中 for folder in parent.Folders: #遍历tse里面的子文件 found = self.TraverseTestItem(folder, testf) #添加到Test Module集合中 class CanoeMeasurementEvents(object): """Handler for CANoe measurement events""" def OnStart(self): CanoeSync.Started = True CanoeSync.Stopped = False print("< measurement started >") def OnStop(self) : CanoeSync.Started = False CanoeSync.Stopped = True print("< measurement stopped >") class CanoeTestModule: """Wrapper class for CANoe TestModule object""" def __init__(self, tm): self.tm = tm self.Events = DispatchWithEvents(tm, CanoeTestEvents) self.Name = tm.Name self.IsDone = lambda: self.Events.stopped self.Enabled = tm.Enabled def Start(self): if self.tm.Enabled: self.tm.Start() self.Events.WaitForStart() class CanoeTestConfiguration: """Wrapper class for a CANoe Test Configuration object""" def __init__(self, tc): self.tc = tc self.Name = tc.Name self.Events = DispatchWithEvents(tc, CanoeTestEvents) self.IsDone = lambda: self.Events.stopped self.Enabled = tc.Enabled def Start(self): if self.tc.Enabled: self.tc.Start() self.Events.WaitForStart() class CanoeTestEvents: """Utility class to handle the test events""" def __init__(self): self.started = False self.stopped = False self.WaitForStart = lambda: DoEventsUntil(lambda: self.started) self.WaitForStop = lambda: DoEventsUntil(lambda: self.stopped) def OnStart(self): self.started = True self.stopped = False print("<", self.Name, " started >") def OnStop(self, reason): self.started = False self.stopped = True print("<", self.Name, " stopped >") # ----------------------------------------------------------------------------- # main # ----------------------------------------------------------------------------- #创建CanoeSync实例 print("Create CANoe Application") LoadStartTime = datetime.now() print("LoadStartTime= ",str(LoadStartTime)) app = CanoeSync() #调用Application对象的Open方法,打开相关的CANoe工程 # loads the sample configuration app.Load('Evergrande_CANFD_SwTest.cfg') LoadFinishTime = datetime.now() print("LoadFinishTime= ",str(LoadFinishTime)) print("LoadTime= ",(LoadFinishTime-LoadStartTime).seconds,"s") #加载Test Module # add test modules to the configuration print("LoadTestSetup") app.LoadTestSetup('TestTestEnvironmentdemo.tse') #加载Test Unit(基于vTESTstudio生成) # add a test configuration and a list of test units #print("LoadTestConfiguration") #app.LoadTestConfiguration('TestConfiguration', ['TestConfigurationEasyTestEasyTest.vtuexe']) # 启动CANoe工程 # start the measurement print("Start Application") app.Start() #启动测试节点 # runs the test modules print("Start TestModule") app.RunTestModules() #启动测试单元 # runs the test configurations #app.RunTestConfigs() #主线程挂起 # wait for a keypress to end the program #print("Press any key to exit ...") #while not msvcrt.kbhit(): # DoEvents() # 停止CANoe工程 # stops the measurement print("Stop Application") app.Stop()
*** 作实例
1-配置CANoe 工程名及该py代码与工程的相对路径
2-配置Test Module及该py代码与加载Test Module的相对路径
3-运行py代码
结果:
调试过程中遇到的问题及解决方法
Otherwise the issue of “pywintypes.com_error: (-2147352567, ‘发生意外。’, (0, None, None, None, 0, -2147467259), None)” will happen!!!
发生情况1:拟打开的CANoe工程正在运行
解决办法:确保拟打开的CANoe工程处于未运行状态
发生情况2:拟加载的Test Module(XX.tse)已经被加载到工程中了
解决办法:确保拟加载的Test Module(XX.tse)未被加载到工程中
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)