全部产品
云市场

在线录制自定义操作

更新时间:2019-09-02 11:58:03

title: 自定义操作

自定义操作的使用与开发

1. 介绍


MQC 专有云平台除了已经支持的步骤外,为了满足测试工程师在实际编写录制测试用例过程中的非通用性需求,功能测试开放了自定义操作的能力,开发工程师可以通过这项能力开发满足实际测试用例需求,满足 app 业务需求的步骤。

自定义操作的入口在 用例库 -> 自定义操作 如图:1-1

2. 开发规范


2.1 目前自定义操作具有以下特性:

  • 需要基于 appium 引擎与 python2.7 语言开发;
  • 自定义操作仅与应用平台(Android,iOS)相关,即自定义操作对相同平台的应用是全局共享的,因此自定义操作的函数名不应也不能重复;
  • 自定义操作作为一个功能测试步骤插入到正常的用例脚本中执行,一般用于实现与业务或用例场景相关的常用逻辑。

对于任意一个自定义操作,其都应该是一个符合约定与语法的 python 类,如下:

  1. class className():
  2. def setAppium(self, driver=None, step=None):
  3. self.driver = driver
  4. self.step = step
  5. def run(self):
  6. #code

必需:

  • className: 为类名,用于表示一个操作,是全局唯一的。
  • setAppium: 为初始化接口,在执行这个操作前,脚本会通过 setAppium 传入当前操作可能需要的参数
    • driver: 即 appium driver,用于与 appium 通信并执行 appium 相关操作
    • step: 即当前步骤的参数,这是一个 {key(string):value(string)} 形式的 dict

非必需:

  • from AppiumLib import AppiumLib: AppiumLib 是 MQC 功能测试为更加便利调用 appium 接口封装的 api, 其中大部分接口非常实用,可以在 groovy/AppiumLib.py 中找到相关源码实现
  • 其他库: MQC 在 appium client 的执行环境中除标准库外,提供安装有如下第三方库,Appium-Python-Client, selenium, matplotlib, cv2, numpy, pycurl, subprocess32, MySQL-python, cx-Oracle, ibm_db

2.2 appiumLib 介绍

AppliumLib是mqc开发并提供的封装好的设备操作接口,具有良好的稳定性与兼容性,开发者可以到 <系统管理->测试脚本管理> 中下载AppiumLib.py.groovy文件。

初始化

  1. from AppiumLib import AppiumLib
  2. appiumLib = AppiumLib(driver)

查找某个控件

  1. ############
  2. # xpath: the xpath to locate element
  3. # id: resourceid
  4. # index: the index of resource_id if it is duplicated
  5. # desc: the content-desc of element
  6. # wait: the overtime to find the element
  7. ############
  8. ele = appiumLib.waitUntil(xpath, id, index, desc, wait=10)

长按

  1. #############
  2. # xpath: the xpath to locate element
  3. # id: resourceid
  4. # index: the index of resource_id if it is duplicated
  5. # desc: the content-desc of element
  6. # time: the duration to press on
  7. # wait: the overtime to find the element
  8. #############
  9. appiumLib.longtouch(xpath=None, id=None, index=None, desc=None, time=1000, wait=6):

输入

  1. #############
  2. # xpath: the xpath to locate element
  3. # id: resourceid
  4. # index: the index of resource_id if it is duplicated
  5. # desc: the content-desc of element
  6. # input: the text to input
  7. # wait: the overtime to find the element
  8. #############
  9. appiumLib.input(xpath=None, id=None, index=None, desc=None, input=None, wait=6):

滑动

  1. #############
  2. # points
  3. # [{"x":coordinate-x, "y":coordinate-y},{"x":coordinate-x, "y":coordinate-y},{"x":coordinate-x, "y":coordinate-y}……]
  4. # duration
  5. # swipe duration
  6. #############
  7. appiumLib.swipe(self, points=None, duration=1000)

重启被测应用 appiumLib.restartApp()清除应用缓存 appiumLib.reset()执行shell命令

  1. ##############
  2. # command
  3. # 如:dumpsys | grep "DUMP OF SERVICE"
  4. ##############
  5. appiumLib.shell(command)

截图

  1. filePath = appiumLib.screencap()

3. 使用示例


  • 计算两个参数 param1,param2 的差并且将返回值保存到参数 result 中
  1. import desired_capabilities
  2. class minus():
  3. def setAppium(self, driver=None, step=None):
  4. self.driver = driver
  5. self.step = step
  6. def run(self):
  7. result = step.get("param1") - step.get("param2")
  8. step.put("result", result)
  • 打开 webview 调试模式:这是一个用于打开不同内核 webview 调试模式的代码,入参为 platform(tencent,chrome)
  1. from AppiumLib import AppiumLib
  2. from time import sleep
  3. class OpenWebviewDebug():
  4. def setAppium(self, driver=None, step=None):
  5. if driver is not None:
  6. self.driver = driver
  7. self.appiumLib = AppiumLib(self.driver)
  8. if step is not None:
  9. self.step = step
  10. def run(self):
  11. platform = self.step.get("platform")
  12. self.appiumLib.openWebviewDebug(platform)
  13. # 点击 永久生效
  14. self.appiumLib.touch(xpath="//android.widget.CheckBox[@text='永久生效' or @content-desc='永久生效']")
  15. # 点击 确定
  16. self.appiumLib.touch(xpath="//android.widget.TextView[@text='确定' or @content-desc='确定']")
  17. sleep(2)

如图设置入参 platform, 则 platform 会作为 step 的一个 key 传入到当前操作中, 在描述中通过 ${platform},该参数会被解析为在线录制的一个可操作参数提供给测试使用:1-21-3

  • 如何调用数据库并且获取数据到参数中

    1. import MySQLdb
    2. class className():
    3. def setAppium(self, driver=None, step=None):
    4. self.driver = driver
    5. self.step = step
    6. self.host = self.step.get("host") # host为外部传入参数
    7. self.port = 3306
    8. self.user = self.step.get("user") # user为外部传入参数
    9. self.passwd = self.step.get("passwd") # passwd为外部传入参数
    10. self.use_database = self.step.get("use_database") #use_database为外部传入参数
    11. self.sql = self.step.get("sql") # sql为外部传入参数
    12. def run(self):
    13. #code
    14. conn = MySQLdb.connect(
    15. host=self.host,
    16. port=self.port,
    17. user=self.user,
    18. passwd=self.passwd
    19. )
    20. cursor = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
    21. cursor.execute(self.use_database) # 发送sql语句
    22. cursor.execute(self.sql)
    23. devices = cursor.fetchall()
    24. asset_num = devices[0]["asset_num"]
    25. self.step["asset_num"] = asset_num # 将从数据库获取的数据传入外部参数

将上述代码添加为代码块,并设置参数,参数名与代码参数一致1-4设置参数池的值1-5将从数据库取的值传出,并作为参数传入之后的步骤中1-6

  • 连续点击某一控件
  1. import AppiumLib
  2. class clicksByxpath():
  3. #interface to set appium params
  4. def setAppium(self, driver=None, step=None):
  5. self.driver = driver
  6. self.step = step
  7. self.xpath = step.get("xpath")
  8. self.times = step.get("times")
  9. def run(self):
  10. #add main code here
  11. el = self.driver.find_element_by_xpath(self.xpath)
  12. for i in range(int(self.times)):
  13. el.click()
  14. print '第%d次点击'%(i+1)
  15. print self.times

平台展示:Xpth可以使用在线录制,点击控件后的生成步骤,复制步骤中的xpath粘贴过来即可ziding-1针对步骤进行编辑:ziding-2

  • 【技术支持】 如果遇到问题,可以注册钉钉,加入移动测试沟通客服群:11762195