05-iOS appuim +python+自动化测试

257 阅读3分钟

效果:

链接: pan.baidu.com/s/14UxH8lzo…  提取码: t1hc

步骤:

第一步:下载并运行桌面app appuim service 的

/Applications/Appium\ Server\ GUI.app/Contents/Resources/app/node_modules/appium/node_modules/appium-webdriveragent目录下的xcode项目到设备

1.1 确保lib 和 runner 的boundID和配置文件包含了当前的设备

1.2 选择 runner ,在command+u运行测试用例,只到看到控制台出现对应的地址即可,设备上有弹框需要同意下

关于下载地址和webdriveragent配置错误问题的修复以参考:配置webdriveragent

配置webdriveragent不需要用公司的证书信息,用自己的开发证书就行,只需要把runner跑到自己手机即可;

第二步:选择mac的桌面app appuim service(host:127.0.0.1 port:4327),启动session

第三步:选择appuim inspector 配置(可以选择界面元素信息,用于脚本匹配到指定的元素) 可选运行

#真机:
{
  "platformName": "iOS",
  "appium:platformVersion": "15.5",
  "appium:deviceName": " iPhone 6s Plus",
  "appium:automationName": "XCUITest",
  "appium:bundleId": "xxx", #app boundle id 必须设置 
  "appium:udid": "xxx", #真机设备的udid
  "appium:app": "xxx/xxx.app" #app的路径这里是绝对路径,可以在xcode项目的product找到app地址
}
#测试机:
{ "platformName": "iOS", "deviceName": "iPhone Simulator", "automationName": "XCUITest", "platformVersion": "14.5", "app": "xxx/xxx.app" }

第四步:可以执行脚本 (如果不知道元素的信息可以运行mac appuim 分析工具里面有元素的详细信息)

from appium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from appium.webdriver.common.touch_action import TouchAction
import time
import sys
import os

def end_app():
    driver.terminate_app('xxx') # xxx为bound id 

def installApp():
    is_install=driver.is_app_installed('xxx'); # xxx为bound id 
    if is_install==1:
        driver.install_app('xxx/xxx.app'); #app的路径这里是绝对路径,可以在xcode项目的product找到app地址
def createSession():
    desired_caps = {
        'platformName': 'iOS',
        'platformVersion': '15.5',
        'deviceName': 'iPhone 6s Plus',
        'udid': 'xxx',  # 设备udid
        'app': 'xxx/xxx.app',   #app的路径这里是绝对路径,可以在xcode项目的product找到app地址
        'bundleId':'xxx', # xxx为bound id
        'newCommandTimeout': 60,
        'automationName': 'Appium',
        'noReset': True
    }
    global driver
    driver=webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
    time.sleep(3)

def stopSesssion():
    driver.quit()

def snapScreen():
    screenshotBase64=driver.get_screenshot_as_base64()

def write_start_address():
    start_address_field=driver.find_element_by_ios_predicate("value == '输入起点地址'")
    start_address_field.click()
    address_poi_img=driver.find_element_by_ios_predicate("type == 'XCUIElementTypeImage'")
    address_poi_field=driver.find_element_by_ios_predicate("label == '请输入关键字'")
    address_poi_field.send_keys("弘源首著大厦")
    time.sleep(3)
    search_poi_cell=driver.find_element_by_xpath("//XCUIElementTypeApplication[@name='前端路测']/XCUIElementTypeWindow[1]/XCUIElementTypeOther[2]/XCUIElementTypeOther[1]/XCUIElementTypeTable/XCUIElementTypeCell[2]")
    search_poi_cell.click()
    time.sleep(2)

def write_end_address():
    end_address_field=driver.find_element_by_ios_predicate("value == '输入终点地址'")
    end_address_field.click()
    address_poi_img=driver.find_element_by_ios_predicate("type == 'XCUIElementTypeImage'")
    address_poi_field=driver.find_element_by_ios_predicate("label == '弘源首著大厦'")
    address_poi_field.send_keys("金隅嘉华大厦")
    time.sleep(3)
    search_poi_cell=driver.find_element_by_xpath("//XCUIElementTypeApplication[@name='前端路测']/XCUIElementTypeWindow[1]/XCUIElementTypeOther[2]/XCUIElementTypeOther[1]/XCUIElementTypeTable/XCUIElementTypeCell[1]")
    search_poi_cell.click()
    time.sleep(2)

def start_navi():
    startBtn=driver.find_element_by_ios_predicate("label == '开始导航' AND name == '开始导航' AND value == '开始导航'")
    startBtn.click()
    time.sleep(2)

def stop_navi():
    stopBtn=driver.find_element_by_ios_predicate("label == '结束导航' AND name == '结束导航' AND type == 'XCUIElementTypeButton'")
    stopBtn.click()
    time.sleep(2)

def simulate_navi_start():
    start_simulate_naviBtn=driver.find_element_by_ios_predicate("label == '模拟导航' AND name == '模拟导航' AND type == 'XCUIElementTypeButton'")
    start_simulate_naviBtn.click()
    time.sleep(2)
    start_play_loc_Btn=driver.find_element_by_ios_predicate("label == '开启GPS回放' AND name == '开启GPS回放' AND type == 'XCUIElementTypeButton'")
    start_play_loc_Btn.click()
    time.sleep(2)

def simulate_navi_stop():
    start_simulate_naviBtn=driver.find_element_by_ios_predicate("label == '模拟导航' AND name == '模拟导航' AND type == 'XCUIElementTypeButton'")
    start_simulate_naviBtn.click()
    time.sleep(2)
    stop_play_loc_Btn=driver.find_element_by_ios_predicate("label == '关闭GPS回放' AND name == '关闭GPS回放' AND type == 'XCUIElementTypeButton'")
    stop_play_loc_Btn.click()
    time.sleep(2)

def swipe():
    # 默认没找到元素
    is_find = False
    # 默认顺序查找,即左滑
    is_sequential_search = True
    app_list=driver.find_element_by_ios_predicate("type == 'XCUIElementTypeScrollView'")
    #获取seekbar控件本身的(尺寸)宽度
    startX=app_list.size.get('width')
    #获取控件中间位置y坐标,(试过后验发现不加尺寸的一半也能操作)
    #控件的坐标Y(应该是左上角的坐标)+控件本身高度的一半
    startY=app_list.location.get('y')+(app_list.size.get('height'))/2
    while is_find is not True:
        try:
            driver.find_element_by_xpath("//XCUIElementTypeCell[@name='Feishu']/XCUIElementTypeOther/XCUIElementTypeOther[2]")
            is_find = True
        except BaseException:
            print("找元素失败 ")
            if is_sequential_search:
                driver.swipe(startX*0.9,startY,startX*0.1,startY, 1000)
            else:
                driver.swipe(startX*0.1,startY,startX*0.9,startY, 1000)
    return is_find

def share_log():
    select_Btn=driver.find_element_by_ios_predicate("label == 'unselect'")
    select_Btn.click()
    share_Btn=driver.find_element_by_ios_predicate("label == '分享'")
    share_Btn.click()
    time.sleep(2)
    is_find = swipe()
    if is_find:
        print("找到飞书按钮啦")
        feishu_cell=driver.find_element_by_xpath("//XCUIElementTypeCell[@name='Feishu']/XCUIElementTypeOther/XCUIElementTypeOther[2]")
        feishu_cell.click()
        time.sleep(2)
        send_self_cell=driver.find_element_by_xpath("//XCUIElementTypeApplication[@name='前端路测']/XCUIElementTypeWindow[4]/XCUIElementTypeOther[3]/XCUIElementTypeOther[2]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeTable/XCUIElementTypeCell[1]")
        send_self_cell.click()
        time.sleep(5)
    else:
        print("飞书按钮寻找失败,终止后续流程!")


if __name__ == '__main__':
    createSession()
    time.sleep(2)
    write_start_address()
    time.sleep(2)
    write_end_address()
    time.sleep(10)
    start_navi()
    time.sleep(2)
    simulate_navi_start()
    time.sleep(2)
    simulate_navi_stop()
    stop_navi()
    time.sleep(2)
    share_log()
    time.sleep(2)
    end_app()

参考文献

juejin.cn/post/684490…

appium.io/docs/en/wri…

www.kancloud.cn/testerhome/…

www.kancloud.cn/testerhome/…

appium.io/docs/en/dri…

www.kancloud.cn/testerhome/…

juejin.cn/column/6963…

www.cnblogs.com/lfr0123/tag… 元素滑动