测试中需要通过FTP通道,将数据发送给服务器,而这个上传的数据要被阻断。在结合RobotFramework测试中,安装的ftplibrary,使用upload_file操作,如果上传动作失败,会抛出异常,使Robotframework测试失败。
而其实我们就是想让他上传失败,不要抛出异常,导致测试失败。这时需要更改下ftplibrary.py。也是非常简单的,我简单记录下:
首先,下载ftplibrary安装包,下载地址:https://pypi.python.org/pypi/robotframework-ftplibrary/1.3
然后执行: Python setup.py install,将其安装。默认应该安装在\Python27\Lib\site-packages\ftplibrary.py.
打开文件后,可以看到upload_file函数的异常处理:
def upload_file(self, localFileName, remoteFileName=None, connId='default'): thisConn = self.__getConnection(connId) outputMsg = "" remoteFileName_ = "" localFilePath = os.path.normpath(localFileName) if not os.path.isfile(localFilePath): raise FtpLibraryError("Valid file path should be provided.") else: if remoteFileName==None: fileTuple = os.path.split(localFileName) if len(fileTuple)==2: remoteFileName_ = fileTuple[1] else: remoteFileName_ = 'defaultFileName' else: remoteFileName_ = remoteFileName try: outputMsg += thisConn.storbinary("STOR " + remoteFileName_, open(localFilePath, "rb")) except ftplib.all_errors as e: raise FtpLibraryError(str(e)) if self.printOutput: logger.info(outputMsg) return outputMsg
它引用了Python自带的ftplib库(\Python\27\Lib\ftplib.py):
打开ftplib.py可以看到对于异常的处理:
# Exception raised when an error or invalid response is received class Error(Exception): pass class error_reply(Error): pass # unexpected [123]xx reply class error_temp(Error): pass # 4xx errors class error_perm(Error): pass # 5xx errors class error_proto(Error): pass # response does not begin with [1-5]
# All exceptions (hopefully) that may be raised here and that aren't
# (always) programming errors on our side
all_errors = (Error, IOError, EOFError)
因为FTP上传文件被阻止后,返回的错误代码是553。所以只需要将Upload_file函数的异常处理再添加一个对“5XX”(class error_perm(Error): pass # 5xx errors)的判断即可。
下面是添加后的样子(红色是添加的异常判断):
def upload_file(self, localFileName, remoteFileName=None, connId='default'): """ Sends file from local drive to current directory on FTP server in binary mode. Returns server output. Parameters: - localFileName - file name or path to a file on a local drive. - remoteFileName (optional) - a name or path containing name under which file should be saved. - connId(optional) - connection identifier. By default equals 'default' If remoteFileName agument is not given, local name will be used. Examples: | upload file | x.txt | connId=ftp1 | | upload file | D:/rfftppy/y.txt | | | upload file | u.txt | uu.txt | | upload file | D:/rfftppy/z.txt | zz.txt | | upload file | D:\\rfftppy\\v.txt | | """ thisConn = self.__getConnection(connId) outputMsg = "" remoteFileName_ = "" localFilePath = os.path.normpath(localFileName) if not os.path.isfile(localFilePath): raise FtpLibraryError("Valid file path should be provided.") else: if remoteFileName==None: fileTuple = os.path.split(localFileName) if len(fileTuple)==2: remoteFileName_ = fileTuple[1] else: remoteFileName_ = 'defaultFileName' else: remoteFileName_ = remoteFileName try: outputMsg += thisConn.storbinary("STOR " + remoteFileName_, open(localFilePath, "rb")) except ftplib.error_perm as e: return str(e) except ftplib.all_errors as e: raise FtpLibraryError(str(e)) if self.printOutput: logger.info(outputMsg) return outputMsg
然后再执行Robot framework测试时,就可以看到,文件被阻止了,但是测试成功,没有返回Fail:
20160316 11:07:52.446 : INFO : 220 (vsFTPd 2.2.2)230 Login successful. 20160316 11:07:52.694 : INFO : ${output} = 553-Requested action not taken (by xxxx:10006) 553 END 20160316 11:07:52.698 : INFO : 553-Requested action not taken (by xxxx:10006) 553 END