使用Robot Test Automation Framework来控制只支持TCL libary的测试设备
有很多测试仪器都只提供了基于Tcl的library,比如SmartBits, Ixia, AX4000。在网络通信测试上,它们都是很常用的通信测试仪器,但是目前的Robot只支持Python,所以就会碰到一个问题,如果来控制这些测试设备,来完成自动化测试呢?
目前我能找到的,主要是两种做法,
两种方法的优缺点分析:
1.第一种方法要求执行自动化测试的机器本地必须安装Tcl以及测试仪器的控制library,有时候,如果对每台客户端都这么要求的话,可能会有点麻烦。优点应该是执行速度比较快,而且可以直接拿到 Tcl liabrary里面函数的返回值
2.第二种方法应该是用起来比较简单,写完的自动化测试脚本,在服务器上可以跑,在本地执行也比较方便。但缺点可能在于每次执行命令前,都需要telnet到服务器去,这样速度会比较慢。还有就是执行完Tcl命令之后,只能通过解析屏幕的输出,来得到你想要的返回值。
上面的想法只是初步想到的,以后在工作中如果有更多的经验,再总结吧
目前上述两种用法,在实际的工作中都有看到,如果我们的工作主要在网络通信测试,那应该会大量用到各种各样的测试仪器,如果我们又要使用Robot Framework的话,那仔细地研究上述两种做法,并比较其中的优劣,甚至考虑设计一种更灵活,兼有两种方法优点的做法,对于自动化测试的效率,应该还是蛮有帮助的。
下面是实际的示例代码,供参考:
1.第一种方法是实例化Tkinter.Tcl,然后在python里面直接调用Tcl语法
class Smartbits : """This class can be used to config and query Smartbits.""" def __init__(self): """initializes each data member""" self.__root = Tkinter.Tcl() """__root: object to use tcl command.""" self.__tclob = None """__tclob: instance of class Smartbits.""" tclScript = """ package require libcmds package require smartlib package require Itcl package require Smartbits 0.9 return [Smartbits #auto] """ self.__sma = self.__root.tk.eval_r(tclScript) def connect(self,ip_addr): """ Connect to the smartbits @param ip_addr: smartbits ip address. @type ip_addr: string @rtype: 0/-1 @return: 0/-1,success/fail @version: 2007-02-18, Chen Xuan, Create. B{Example:} - C{connect('10.15.201.47')} """ tclScript = """ %s Connect -addr %s """%(self.__sma,ip_addr) return self.__root.tk.eval_r(tclScript)
2. 第二种是设置一台中间的代理服务器,然后连到那个服务器上,通过Telnet或者SSH,然后通过Python执行命令并取得命令的返回值,再加以分析,以AX4000为例:
class Ax4000:
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
def __init__(self):
self._telnet_connections = {}
self._current = None
#_oldprompt_dict for contain the prompt before running tclsh
self._oldprompt_dict = {}
self._loglevel = "INFO"
def connect_to_ax4000(self, host, port = 23, user = "public", passwd = "public", prompt = None, lib_with_path='$env(AX4000LIB)', bios_path='$env(AX4000BIOS)'):
""" Connect to ax4000 tcl server where the ax4000 tcl library is installed.
For MS window the loading of ax4000 tcl library and identification of bios path
(ax hwdir) is done.
TO DO: The same (load and ax hwdir) should also be done for 'Linux'. Currently
for loading ax4000 tcl library, the keyword 'Setup Ax4000 Commands Environment'
should be used after connecting to AX4000 server.
| Input Paramaters | Man. | Description |
| host | Yes | Identifies to host |
| port | No | Allows to change the default telnet port |
| user | No | Authentication information |
| passwd | No | Authentication information |
| prompt | No | Allows to set the prompt |
| lib_with_path | No | Allow to define the ax4000 tcl path and library |
| | | e.g. C:/Program Files/tcl/ax4000/tclwin/libax4k.dll |
| bios_path | No | Allow to define the ax4000 bios path |
| | | e.g. C:/Program Files/tcl/ax4000/bios |
"""
if prompt == None or prompt == '': print "prompt", prompt myprompt = [ "%s@.*\$ " % user, "\w:.*>" ] else: myprompt = prompt conn = TelnetConnection(host, port, myprompt, "60sec", "CR") conn.set_loglevel(self._loglevel) ret = conn.login(user, passwd, "login: ", [ "password: ", "Password: " ]) if ret.find("Microsoft") >= 0: self._telnet_connections[conn] = "MS" self._current = conn #record old prompt input dict with telnet connection as key self._oldprompt_dict[conn] = self._current.set_prompt("% ") self._current.write("tclsh") self._current.read_until_prompt() if self._check_if_environment_variable_defined(lib_with_path) == False or \ self._check_if_environment_variable_defined(bios_path) == False: lib_with_path, bios_path = self._get_library_and_bios_path() self.setup_ax4000_commands_environment(lib_with_path, bios_path) else: self._telnet_connections[conn] = "Linux" self._current = conn #record old prompt input dict with telnet connection as key self._oldprompt_dict[conn] = self._current.set_prompt("% ") self._current.write("tclsh") self._current.read_until_prompt() #LINUX BUG if self._check_if_environment_variable_defined(lib_with_path) == False or \ self._check_if_environment_variable_defined(bios_path) == False: lib_with_path, bios_path = self._get_library_and_bios_path() self.setup_ax4000_commands_environment(lib_with_path, bios_path) return conn
def execute_ax4000_command(self, command): """Executes a command within the tcl shell and checks for error. The command is automatically extended by a CR at the end. In case of a TCL exception a Runtime Error is raised. | Input Paramaters | Man. | Description | | command | Yes | The AX4000 TCL command to be executed | """ # catch TCL exception error_code = self.execute_ax4000_command_without_check("catch {%s} result" % command) # print "raw error", error_code error_code = error_code.splitlines()[1].strip() # print "error", error_code result = self.execute_ax4000_command_without_check('puts $result') # check if TCL exception occured #LINUX BUG if not error_code : error_code = '0' if error_code != '0': # self.disconnect_from_ax4000() raise RuntimeError('TCL Error: %s'%result) return result def execute_ax4000_command_without_check(self, command): """Executes a command within the tcl shell without checking for errors. The command is automatically extended by a CR at the end. | Input Paramaters | Man. | Description | | command | Yes | The AX4000 TCL command to be executed | """ self._current.write(command) return self._current.read_until_prompt()