Robot Framework 自动化框架 - 定制自己的library

Robot 自动化框架内置提供了一些library,如OperatingSystem(包含一些常用的的文件操作关键字,如copy文件,创建目录),Telent,Screenshot,String,另外还有一些第三提供的library ,比较常用的如SeleniumLibrary,用于Web自动化测试。但如何定制适合自己项目需求的library呢?

  • 支持的编程语言

支持的语言包括:Python & Java. Robot框架本身就是有Python开发,理所当然支持Python来实现library。当运行时,选择了Jybot,那么你也可以用Java来实现library。

  • Robot框架提供了三种不同的实现library的API
  1. Static API

这是最简单的方式,实现一个python module,在这个module里面有一些functions,或则在module里面有个python 的类,里面有一些方法。通过Java来实现的话,提供一个Class,里面有些public 的method。当import 这个python module, python class或java class这些method就会自动映射为keyword。

有一点需要注意的是,如何判断一个keyword的状态,当执行这个keyword时,是Pass,还是Fail呢?如果在方法里面抛出了异常,那么这个keyword的状态就是Fail.

下面先来看看之前写的一个library,截取了一段代码:

  1. class RemoveSMDLibrary(RuntimeError):  
  2.     '''''A test library providing keyword for SMLD uninstallation related tasks. 
  3.     '''  
  4.   
  5.     #Test library scope  
  6.     ROBOT_LIBRARY_SCOPE = 'GLOBAL'  
  7.     #specifiying library version  
  8.     ROBOT_LIBRARY_VERSION = '0.2'  
  9.     ROBOT_EXIT_ON_FAILURE = True  
  10.       
  11.       
  12.     def __init__(self,is_windows=-1):  
  13.         self._is_windows=is_windows  
  14.         sys.path.append("MyConfigParser.py")  
  15.         logger.console('Add MyConfigParser.py file into Python path!')  
  16.           
  17.     def get_smdsys_path(self,msg=None):  
  18.         logger.console('Get smdsys.ini File...')  
  19.         winsmdsysPath = os.path.expandvars('$systemroot\\smdsys.ini')  
  20.         nonwinsmdsysPath = "/etc/smdsysV2.ini"  
  21.         if os.path.isfile(winsmdsysPath):  
  22.             self._is_windows = 1  
  23.             self._smdsyspath = winsmdsysPath  
  24.         elif os.path.isfile(nonwinsmdsysPath):  
  25.             self._is_windows = 0  
  26.             self._smdsyspath = nonwinsmdsysPath  
  27.         if self._is_windows ==-1:       
  28.             if not msg:  
  29.                 msg="File '%s' does not exist" %winsmdsysPath  
  30.             raise AssertionError(msg)     
  31.       
  32.     def _get_windows_path(self,smdsysPath):  
  33.         config = ConfigParser()  
  34.         config.read(smdsysPath)  
  35.         productPath = config.get("SMDConf","ProductPath")  
  36.         notesiniPath = config.get("DomSvr0","DomSvr0NotesIniPath")  
  37.         return productPath,notesiniPath  
  38.   
  39.     def _get_nonwindows_path(self,smdsysPath):  
  40.         config = ConfigParser()  
  41.         config.read(smdsysPath)  
  42.         SMDInstanceList = config.get("SMDInstances","SMDInstanceList")  
  43.         productPath = config.get(SMDInstanceList,"ProductPath")  
  44.         DomSvr = config.get(SMDInstanceList,"DomSvrISMDSecs")  
  45.         notesiniPath = config.get(SMDInstanceList,DomSvr)  
  46.         return productPath,notesiniPath      
  47.    
  48.     def get_notesini_path(self):  
  49.         if self._is_windows == 1:  
  50.             return self._get_windows_path(self._smdsyspath)      
  51.         else:  
  52.             return self._get_nonwindows_path(self._smdsyspath)  
 

当一个Pyhton class中,会忽略以_开头的function,不认为是keyword。

看一下实际应用在ride中如何导入:

2012-09-15_231402

因为Python module名和class的名字是一样的,所以可以直接用module名,如果不一样,就需要以这样的格式来导入mymodule.myclass来导入library。看下这个参数,这个参数是传递给构造函数的。

2012-09-15_231424

如果你的library导入成功了,那么这些library中的keyword颜色就会变成这样,把鼠标放上去,按ctrl就是出现提示。

  2.  Dynamic API

在keywords状态,logging和返回值方面,dynamic library API 和static library API是一样的。唯一的不同是Robot Framework如何判别导入的library里面的keywords。static library API是通过反射机制来实现的,dynamic library采用一种特别的方式。

就static library keywords而言,所有的keywords必须在一个class,或modules中。而dynamic library API,你的keywords可以分布在不同的class中。

Dynamic API中必须实现两个方法:run_keyword 和 get_keyword_names,Robot Framework通过这两个方法,得知在library实现了哪些keyword,怎么调用这些keyword.

有个第三方的库JavalibCore,实现了run_keyword和get_keyword_names,用户只需要实现自己的keyword就可以了。这里就不举例子了,建议看javalibcore的源码。

3. Hybrid API

Hybrid library API是间于static API, dynamic API之间的。

和dynamic library API 一样,你需要提供一个get_keyword_names方法,来返回这个library 可以提供的所有keywords的名字。还有一点,Hybrid library API 只适用于Python,对于Java不可以的。

下面之间看一个例子,这个library的实现就是采用的Hybrid API方式。

  1. class Smdauto(RuntimeError):  
  2.     '''''A test library providing keywords for SMLD Automation 
  3.     '''  
  4.       
  5.     ROBOT_LIBRARY_SCOPE = 'GLOBAL'  
  6.     ROBOT_LIBRARY_VERSION = '0.1'  
  7.     ROBOT_EXIT_ON_FAILURE = True  
  8.       
  9.     def __init__(self):  
  10.         locator=KeywordsServiceLocator()  
  11.         #kw={ 'tracefile' : sys.stdout, 'auth' : ( AUTH.httpbasic,  'test1', '111111' ) }  
  12.         #self._port_type=locator.getKeywords(**kw)  
  13.         self._port_type=locator.getKeywords()  
  14.         self._notes_mail = None  
  15.         self._lib_kws=self._notes_mail_kws=None  
  16.           
  17.     def get_keyword_names(self):  
  18.         return self._get_library_keywords() + self._get_notes_mail_keywords()  
  19.   
  20.     def _get_library_keywords(self):  
  21.         if self._lib_kws is None:  
  22.             self._lib_kws = [ name for name in dir(self)  
  23.                               if not name.startswith('_'and name != 'get_keyword_names'  
  24.                               and inspect.ismethod(getattr(self, name)) ]  
  25.         return self._lib_kws  
  26.           
  27.     def _get_notes_mail_keywords(self):  
  28.         if self._notes_mail_kws is None:  
  29.             notes_mail=self._get_notes_mail()  
  30.             self._notes_mail_kws=[ name for name in dir(notes_mail)  
  31.                                if not name.startswith('_'and inspect.ismethod(getattr(notes_mail, name)) ]  
  32.         return self._notes_mail_kws  
  33.           
  34.     def __getattr__(self,name):  
  35.         if name not in self._get_notes_mail_keywords():  
  36.             raise AttributeError(name)  
  37.         notes_mail = self._notes_mail is None and self._get_notes_mail() or self._notes_mail  
  38.         print dir(notes_mail)  
  39.         return getattr(notes_mail,name)  
  40.           
  41.     def _get_notes_mail(self):  
  42.         return NotesMail()     

其实,Hybrid API的实质就是应用Python中委派机制,即__getattr__内置函数,当尝试调用一个不存在的方法时,Python会默认调用__getattr__。

首先,先来看get_keyword_names,这个方法返回了这个libray包含的所有的keywords,它调用了有两个method,第一个返回这个class中所有不是以_开头的方法名,另一个返回一个额外的class中的方法。当执行的method不在这个class中的时候,就会调用__getattr__,从而实现委派调用。

 

参考资料:http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html?r=2.7.4#remote-library-interface

posted on   matt_chen  阅读(5846)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

导航

< 2012年9月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 1 2 3 4 5 6

统计

点击右上角即可分享
微信分享提示