创建RobotFramework可使用的自定义Library(二)

RobotFramework中创建自定义Library的方法 (二)

介绍另一种方式在RF中创建可被识别和调用的关键字方法。

借鉴AppiumLibrary和RF内置关键字的编写方法:

使用这种方式创建自定义库需要注意以下几点:
1. 库的名称与初始化类的名称相同
2. 初始化类在多重继承时选择需要的功能类
3. 关键方法的构造类可继承KeywordGroup类,该类的方法参见AppiumLibrary,文中我会给出具体的代码实现,可以自建一个py文件代替。

详细内容如下:

主程序代码:

from Connect import *
from Start import *

class TestLibrary(Connect,
                  Start):
    """
    #注释1. 
    使用多重继承的方式,在此处加载所有自建类的方法
    这里举例只加了Connect和Start,根据自己需要增加
    此处的TestLibrary也可以不写,写成__init__
    关键是整个文件夹的名称要和你定义的库名称保持一致,才可以被RF识别调用
    """

    ROBOT_LIBRARY_SCOPE = "GLOBAL"
    ROBOT_LIBRARY_VERSION = VERSION

    def __init__(self):
        for base in TestLibrary.__bases__:
            base.__init__(self)
    #注释2. 此处的初始化让继承所有父类都执行相应的初始化

功能类代码:

创建的Connect.py文件:

from keywordgroup import KeywordGroup

class TestConnect(KeywordGroup):

    def __init__(self):
        pass
        #根据需要可自行进行增加

    def connect(self, connect_way):
        self.serialobject.Open()

创建的Start.py文件:

class TestStart(KeywordGroup):

    def __init__(self):
        pass
        #根据需要可自行进行增加

    def start(self, connect_way):
        self.serialobject.Start()

对于注释1,这种构造关键字的方式其实就是继承所有父类的对象和方法,需要确保父类的方法不重名,否则Python中的多重继承是按照从左往右依次继承,方法重名则被覆盖调用,到时候你都不知道调用的是哪一个。
有关多重继承的坑详见:

当心掉进Python多重继承里的坑

对于注释2,该步骤的目的是将所有的继承类进行初始化操作,可以在这一步实例化所有对象。
文中的base打印出来其实就是Connect和Start创建的类:TestConnect和TestStart:

<class 'TestLibrary.Connect.TestConnect'>
<class 'TestLibrary.Start.TestStart'>

大家可以看到,在创建功能类的时候,每个类都继承了KeywordGroup类,该方法是借鉴AppiumLibrary的实现行为,当然我在查看了RF的BuildIn功能后,发现不用该方法也可以,在BuiltIn.py文件中是这么构造内置类的:

class BuiltIn(_Verify, _Converter, _Variables, _RunKeyword, _Control, _Misc):
    ROBOT_LIBRARY_SCOPE = 'GLOBAL'
    ROBOT_LIBRARY_VERSION = get_version()

RF内置的方法也是通过直接继承各个方法类来调用,因此仅靠继承的方式,在RF中也已经可以调用所有方法。之所以让大家在方法类中继承KeywordGroup是为了在出错时可以更好的查找原因。对应的也就是BuiltIn.py文件中RobotNotRunningError类的实现,具体实现详见下方:

关键字基类:KeywordGroup的代码实现:

# -*- coding: utf-8 -*-

import sys
import inspect
try:
    from decorator import decorator
except SyntaxError:  # decorator module requires Python/Jython 2.4+
    decorator = None
if sys.platform == 'cli':
    decorator = None  # decorator module doesn't work with IronPython 2.6


def _run_on_failure_decorator(method, *args, **kwargs):
    try:
        return method(*args, **kwargs)
    except Exception as err:
        self = args[0]
        if hasattr(self, '_run_on_failure'):
            self._run_on_failure()
        raise


class KeywordGroupMetaClass(type):
    def __new__(cls, clsname, bases, dict):
        if decorator:
            for name, method in dict.items():
                if not name.startswith('_') and inspect.isroutine(method):
                    dict[name] = decorator(_run_on_failure_decorator, method)
        return type.__new__(cls, clsname, bases, dict)


class KeywordGroup(object):
    __metaclass__ = KeywordGroupMetaClass

可以将该代码复制后丢到一个文件中,命名为keywordgroup,在方法类中导入并继承即可。

如果不按照这种方式实现,大家也可以再去看一下RF中的BuildIn.py文件,其实也有一个基类:_BuiltInBase,在其中有这样一个方法:

    def _get_context(self, top=False):
        ctx = EXECUTION_CONTEXTS.current if not top else EXECUTION_CONTEXTS.top
        if ctx is None:
            raise RobotNotRunningError('Cannot access execution context')
        return ctx

其中RobotNotRunningError的具体方法实现和KeywordGroup的方法类似。

按照上述方法创建主程序和功能类,采用继承的方式,将整个文件夹放在D:\Python\Lib\site-packages路径下(即你安装的Python路径),即可在RF中导入库进行使用了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值