如何在Robot Framework中使Trace32的self.t32api保持全局作用域?
问题
我开发了一个与Lauterbach Trace32通信的Robot Framework测试套件,希望通过循环调用函数并在每次循环中设置断点。已编写Python脚本作为Robot库,但仅第一次循环的断点生效,后续循环失效。现需让库中的self.t32api保持全局作用域,直至测试完全执行完毕。
test.robot 文件
import os *** Settings *** Documentation simple test script to control Trace32 Library Collections Library can.Trace32 Suite Setup Suite Teardown *** Variables *** ${temp} 1 *** Test Cases *** Check Input and Output [Documentation] test script [Setup] #Retrive Data . This list has 5 values ${MainList} Create List #start debugger start Debugger #connect debugger Connect Debugger #Iterate 5 times FOR ${UserAttribute} IN @{MainList} #sleep 1 sec Sleep 1 seconds #call for breakpoint break Debugger ${temp} +=1 END Disconnect Debugger [Teardown]
Trace32 Python库脚本
import time import ctypes from ctypes import c_void_p import enum T32_DEV = 1 class Trace32: def start_Debugger(self): self.t32api = ctypes.cdll.LoadLibrary('D:/test/api/python/t32api64.dll') self.t32api.T32_Config(b"NODE=",b"localhost") self.t32api.T32_Config(b"PORT=",b"20000") self.t32api.T32_Config(b"PACKLEN=",b"1024") rc = self.t32api.T32_GetChannelSize() ch1 = ctypes.create_string_buffer(rc) self.t32api.T32_GetChannelDefaults(ctypes.cast(ch1,ctypes.c_void_p)) ch2 = ctypes.create_string_buffer(rc) self.t32api.T32_GetChannelDefaults(ctypes.cast(ch2,ctypes.c_void_p)) self.t32api.T32_SetChannel(ctypes.cast(ch2,c_void_p)) def Connect_Debugger(self): rc = self.t32api.T32_Init() rc = self.t32api.T32_Attach(T32_DEV) def breakpoint_Debugger(self): rc = self.t32api.T32_Ping() time.sleep(2) rc = self.t32api.T32_Cmd(b"InterCom M7_0 Break") time.sleep(3) rc = self.t32api.T32_Cmd(b"InterCom M7_0 Go") time.sleep(2) rc = self.t32api.T32_Cmd(b"InterCom M7_0 break.Set My_func") time.sleep(2) def Disconnect_Debugger(self): rc = self.t32api.T32_Exit()
解决方案
问题根源是Robot Framework默认会为关键字/测试用例创建新的库实例,导致每次循环调用时t32api被重新初始化,丢失了之前的连接状态。以下两种方式可实现t32api的全局作用域:
方式1:使用类静态属性
将t32api定义为类的静态变量,确保整个测试过程中只初始化一次连接:
import time import ctypes from ctypes import c_void_p import enum T32_DEV = 1 class Trace32: # 类级静态属性,全局共享 t32api = None def start_Debugger(self): if Trace32.t32api is None: Trace32.t32api = ctypes.cdll.LoadLibrary('D:/test/api/python/t32api64.dll') Trace32.t32api.T32_Config(b"NODE=",b"localhost") Trace32.t32api.T32_Config(b"PORT=",b"20000") Trace32.t32api.T32_Config(b"PACKLEN=",b"1024") rc = Trace32.t32api.T32_GetChannelSize() ch1 = ctypes.create_string_buffer(rc) Trace32.t32api.T32_GetChannelDefaults(ctypes.cast(ch1,ctypes.c_void_p)) ch2 = ctypes.create_string_buffer(rc) Trace32.t32api.T32_GetChannelDefaults(ctypes.cast(ch2,ctypes.c_void_p)) Trace32.t32api.T32_SetChannel(ctypes.cast(ch2,c_void_p)) def Connect_Debugger(self): rc = Trace32.t32api.T32_Init() rc = Trace32.t32api.T32_Attach(T32_DEV) def breakpoint_Debugger(self): rc = Trace32.t32api.T32_Ping() time.sleep(2) rc = Trace32.t32api.T32_Cmd(b"InterCom M7_0 Break") time.sleep(3) rc = Trace32.t32api.T32_Cmd(b"InterCom M7_0 Go") time.sleep(2) rc = Trace32.t32api.T32_Cmd(b"InterCom M7_0 break.Set My_func") time.sleep(2) def Disconnect_Debugger(self): if Trace32.t32api is not None: rc = Trace32.t32api.T32_Exit() Trace32.t32api = None # 测试结束后清理资源
方式2:配置Robot Framework库为单例
在Robot Framework的库导入语句中添加SINGLETON参数,强制整个测试套件只创建一个库实例:
*** Settings *** Documentation simple test script to control Trace32 Library Collections Library can.Trace32 SINGLETON
额外修正点
- 测试用例中
break Debugger关键字与库中breakpoint_Debugger方法名不匹配,需统一为breakpoint Debugger或修改方法名为break_Debugger ${MainList}需添加实际元素(如Create List 1 2 3 4 5),否则循环不会执行- 建议将
start Debugger/Connect Debugger移至Suite Setup,Disconnect Debugger移至Suite Teardown,避免重复初始化
内容的提问来源于stack exchange,提问作者user2986042
相关产品推荐
相关产品推荐

