Robot Framework - 将Appium驱动传递给Python脚本

4 投票
3 回答
7618 浏览
提问于 2025-04-18 14:16

我正在用Python把Robot Framework和Appium结合起来。不过,我不知道怎么把在Robot Framework中创建的Appium驱动传递给一个自定义的Python脚本。

我的环境:

  • Mac OS - Mavericks
  • Appium 1.2(通过home brew安装)
  • 最新的Robot Framework(通过pip安装)
  • 最新的Robot Framework的Appium库(通过pip安装)

我有一个可以工作的Appium Python脚本,但我想开始用Robot Framework来处理实际的测试。

这是我工作中的Python脚本的一部分代码:

wd = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
wd.find_element_by_name("Start").click()
wd.find_element_by_xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[1]").click()
wd.execute_script("var vKeyboard = target.frontMostApp().keyboard(); vKeyboard.typeString(\"Test Text\");")
wd.execute_script("var vKeyboard = target.frontMostApp().keyboard(); vKeyboard.buttons()['Return'].tap();")

如你所见,由于应用程序的工作方式,我需要在脚本中使用execute_script。

但是Robot Framework的Appium库没有提供execute_script这个功能,所以我需要在一个Python库中自己写。

这是我开始的Robot测试脚本,它在我需要执行execute_script之前是可以工作的:

TestStart
    Open Application   ${REMOTE_URL}    ${PLATFORM_NAME}    ${PLATFORM_VERSION}    ${DEVICE_NAME}    ${APP}
    Click Element    name=Start
    Click Element    xpath=//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[1]

我的问题是,如何把在“打开应用程序”中创建的驱动实例传递给Python脚本?

我有一个Python脚本,里面有以下内容:

def KeyboardType(driver):
    driver.execute_script("var vKeyboard = target.frontMostApp().keyboard(); vKeyboard.typeString(\"hi there\");")

但是,我似乎无法把Robot Framework脚本中的驱动传递给这个Python脚本。

我尝试通过以下方式把“打开应用程序”的结果设置为一个变量:

${Driver}  Open Application   ${REMOTE_URL}    ${PLATFORM_NAME}    ${PLATFORM_VERSION}    ${DEVICE_NAME}    ${APP}
KeyboardType  ${Driver}

但我收到了这个错误:

AttributeError: 'str'对象没有'execute_script'这个属性

我还尝试把“获取当前上下文”的结果传递到Python脚本中,但我得到了:

AttributeError: 'unicode'对象没有'execute_script'这个属性

我该如何把Robot Framework创建的驱动传递到Python脚本中呢?

3 个回答

2

这是你问题的解决方案 :)

from robot.libraries.BuiltIn import BuiltIn

def get_current_driver():
    return BuiltIn().get_library_instance('AppiumLibrary')._current_application()
2

感谢Bryan Oakley的回复,他给我指明了方向,解决办法是对Appium库进行子类化。

我做了以下修改使其能够正常工作:

我的主要Robot Framework测试文件不再引用Appium框架,而是只引用了我自定义的Python文件。

我的自定义Python文件现在是对Appium库的子类化,这样我就可以访问到_current_application()这个功能。

我的自定义Python类现在看起来是这样的:

from AppiumLibrary import AppiumLibrary

class Custom(AppiumLibrary):
    def get_driver_instance(self):
        return self._current_application()

    def KeyboardType(self, textToType):
        self._current_application().execute_script("var vKeyboard = target.frontMostApp().keyboard(); vKeyboard.typeString(\"" + textToType + "\");")

    def PressKeyboardButton(self, buttonToPress):
        self._current_application().execute_script("var vKeyboard = target.frontMostApp().keyboard(); vKeyboard.buttons()['" + buttonToPress + "'].tap();")

Robot Framework文件现在看起来是这样的:

TestStart
    Open Application   ${REMOTE_URL}    ${PLATFORM_NAME}    ${PLATFORM_VERSION}    ${DEVICE_NAME}    ${APP}
    Click Element    name=Start
    Click Element    xpath=//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[1]
    KeyboardType    Test 123
    PressKeyboardButton    Return

注意:此时,我不需要将打开的应用程序设置为一个变量,因为子类已经自动可以访问它。不过,如果需要的话,我可以通过“获取驱动实例”轻松地将其设置为变量。

谢谢你的帮助,Bryan!

3

我现在不使用appium,所以不能给出确切的答案。不过,有人问过一个类似的问题,关于selenium,那个问题是需要实际的webdriver对象。你可以查看这个问题:将现有的Webdriver对象传递给Robot Framework的自定义Python库

简单来说,你可以尝试去扩展appium库,这样你的关键词就能访问appium的内部功能,或者你可以通过调用 BuiltIn().get_library_instance('Selenium2Library 来获取库的句柄。

关于后面这种方法的更多信息,可以查看从Robot Framework获取活动库实例,这个内容在Robot Framework用户指南中。

撰写回答