UI测试自动化-Web-Python-Appium

一、Appium-ADB

1.Appiym设计原理:

Appium Web Server

(1)C/S架构,appium的核心是一个web服务器,提供了一套接口,会接收客户端发过来的命令,然后在移动设备上运行命令,最后把运行结果通过HTTP响应包返回给客户端

(2)session,每个client连接到server以后都会创建一个seession,自动化始终围绕一个session进行

2.应用:

(1)Native App : 原生应用

(2)Web APP: 移动浏览器应用,使用移动平台的浏览器访问的应用

(3)Hybrid App:混合应用,把一个基于webview实现的功能进行包装的应用

3.ADB

(1)ADB:Android Debug Bridge ,一个手机调试工具

(2)ADB客户端 ---> ADB服务器

(3)ADB客户端:Client端:运行在开发及其中,用来发送adb命令

(4)ADB服务器:Server端,运行在开发及其中,用来管理Client端和手机的Daemin之间的通信

(5)Daemon守护进程:运行在调试设备中,手机或模拟器用来接收并执行 adb 命令

4.adb常用命令

(1)获取包名和界面名:

adb shell dumpsys window | findstr usedApp

包名(package):决定程序的唯一性(不是应用的名字) 获取包名--操作APP的必要条件

界面名(activity):目前可以理解,一个界面名,对应着一个界面

adb shell dumpsys window(窗口)|findstr usedApp

(2)文件传输--上传文件

adb push 电脑的文件路径 手机的文件夹路径

(3)文件传输 --下载文件

adb pull 手机的文件路径 电脑的文件路径

(4)获取手机日志:

日志是APP手工测试必用的工具

(5)APP启动时间:(性能测试)

adb shell am start -W 包名/启动名

ThisTime:该界面(activity)启动耗时(毫秒)

TotalTime:应用自身启动耗时=ThisTime+应用 application 等资源启动时间(毫秒)

WaitTime:系统启动应用耗时=TotalTime+系统资源启动时间(秒)

(6)冷启动:应用程序未启动到启动

热启动:已经启动了,从后台切到前台的时间

5.当测试过程中发现问题后向获取错误日志信息:

(1)打开被测应用程序,进入到触发缺陷的位置

(2)使用查看日志命令:adb logcat

(3)出发缺陷

(4)获取日志信息

(5)重定向 如:adb logcat >D:\test_file\Appium\logcat\try1.log

6.adb常用命令--其它指令

(1)adb install路径/xx.apk 安装 app 到手机

(2)安装 app 到手机 卸载手机上的 app,需要指定包名

(3)adb devices 获取当前电脑已经连接设备和对应的设备号 --测试自动化时使用 会自动启动服务,也就是(5)

(4)adb shell 进入到安卓手机内部的linux系统命令行中

(5)adb start-server 启动 adb 服务端,出 bug 时使用可以重启服务器,先关闭再启动

(6)adb kill-server 停止 adb 服务端,出 bug 时使用可以重启服务器,先关闭再启动

(7)adb --help 查看 adb 帮助,命令记不清楚时有用

(8)adb connectip:端口 连接手机/模拟器

二、Appium -API

1.appium基础操作api:安装、卸载;appium高级api操作:滑动、拖拽;appium手机操作api(按键)

2.移动端自动化--初始化配置项

(1)platformName:需要连接的手机的平台(不限制大小写)

(2)platformVersion:需要连接的手机的版本号(比如 5.2.1的版本可以填写 5.2.1或5.2或5,以此类推)

(3))devicesName:需要连接的手机的设备号(andoird平台下,可以随便写,但是不能不写)

(4)appPackage:需要启动的程序的包名

(5)appActivity:需要启动的程序的界面名

3.设置中文:

desired_caps[*nicodeKeyboard*]=True

desired_caps[*resetKeyborad*]=True

4.获取driver

driver =webdriver.Remote("http://1270.0.1:4723/wd/hub",

desired caps)

python 复制代码
from appium import webdriver
from appium.options.android import UiAutomator2Options



# Appium启动代码示例
"""
对应 Appium-Python-Client 4.2.4 selenium 4.39.0
"""
# 构造配置项
options = UiAutomator2Options()
options.platform_name = 'Android'
options.platform_version = '12.0'
options.device_name = 'emulator-5556'
options.app_package = 'com.android.settings' # 包名
options.app_activity = '.Settings' # 应用名
# 设置为中文
options.set_capability('unicodeKeyboard', True)
options.set_capability('resetKeyboard', True)
# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', options=options)

三、Appium-基础Api:

1.app基础操作-应用跳转

(1)driver.start_activity(appPackage,appActivity)

appPackage:要打开的程序的包名

appActivity:要打开的程序的界面名

python 复制代码
from time import sleep

from appium import webdriver
# from appium.options.android import UiAutomator2Options

# Appium启动代码示例

#定义字典变量
desired_cap={}
# 构造配置项
desired_cap['platformName']='Android'
desired_cap['platformVersion']='12.0'
desired_cap['deviceName']='emulator-5556'
desired_cap['appPackage']='com.android.settings'
desired_cap['appActivity']='.Settings'

# 设置为中文
desired_cap['unicodeKeyboard']=True
desired_cap['resetKeyboard']=True

# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_cap)

"""
    需求:
        1.情动设置后,暂停三秒,打开通讯录
        2.答应当前默认应用包名、启动名
"""
sleep(3)

driver.start_activity(app_package='com.google.android.contacts', app_activity='com.android.contacts.activities.PeopleActivity')


# 打印包名 、启动名
print("当前所在应用包名:",driver.current_package)
print("当前所在应用启动名:",driver.current_activity)
driver.quit()

2.app基础操作-关闭驱动和app

(1)关闭当前操作的app,不会关闭驱动对象

driver.close_app()

(2)退出app应用

driver.quit()

python 复制代码
from appium import webdriver

"""
对应 Appium-Python-Client 4.2.4 selenium 4.39.0
"""
# from appium.options.android import UiAutomator2Options
options = UiAutomator2Options()
options.platform_name = 'Android'
options.platform_version = '12.0'
options.device_name = 'emulator-5556'
options.app_package = 'com.android.settings' # 包名
options.app_activity = '.Settings' # 应用名
# 设置为中文
options.set_capability('unicodeKeyboard', True)
options.set_capability('resetKeyboard', True)
# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', options=options)
# 在初始化后,先检查driver的类型和可用方法
print("Driver类型:", type(driver))
print("Driver的MRO:", type(driver).__mro__)

# 检查是否有 start_activity 方法
print("是否有 start_activity 方法:", hasattr(driver, 'start_activity'))

# 查看所有方法
methods = [method for method in dir(driver) if not method.startswith('_')]
print("可用方法数量:", len(methods))
print("包含 'activity' 的方法:", [m for m in methods if 'activity' in m.lower()])

# 尝试调用 start_activity
if hasattr(driver, 'start_activity'):
    driver.start_activity(
        app_package='com.android.contacts',
        app_activity='com.android.contacts.activities.PeopleActivity'
    )
else:
    print("driver对象没有start_activity方法")
    # 查看driver的实际类
    print(f"driver的实际类是: {driver.__class__}")

3.安装卸载app 是否安装app

(1)部分应用管理平台在安装了app后,会自动进行检测,如已安装了则会显示【启动】

(2)安装app,app_path为安装文件完整路径名

driver.install_app(app_path)

(3)卸载app,app_id为app包名

driver.remove_app(app_id)

(4) 判断app是否变装,app_id为app包名

driver.is app installed(app id)

python 复制代码
from time import sleep

from appium import webdriver

# Appium启动代码示例

#定义字典变量
desired_cap={}
# 构造配置项
desired_cap['platformName']='Android'
desired_cap['platformVersion']='12.0'
desired_cap['deviceName']='emulator-5556'
desired_cap['appPackage']='com.android.settings'
desired_cap['appActivity']='.Settings'

# 设置为中文
desired_cap['unicodeKeyboard']=True
desired_cap['resetKeyboard']=True

# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_cap)

"""
    需求:
        1.判断微信是否安装,安装--->卸载;没有安装:安装
        2.启动设置界面
        3.置于后台 3秒
        4.关闭设置界面
        5.关闭app驱动
"""
# 判断是否安装 --包名
if driver.is_app_installed("com.tencent.mm"):
    # 卸载
    driver.remove_app("com.tencent.mm")
else:
    # 安装
    driver.install_app(r"D:\test_file\Appium\APK\weixin8066android2980_0x28004234_arm64.apk")

sleep(10)
# 启动设置界面
driver.start_activity('com.android.settings','.Settings')
sleep(3)
# 置于后台3秒
driver.background_app(3)
sleep(3)
# 关闭设置界面
driver.close_app()
print("关闭设置app后获取包名:",driver.current_package)
sleep(3)
# 关闭驱动
driver.quit()

4.app基础操作-置于后台

(1)登陆后置于后台一段时间后,这类安全系数高的APP再重新打开使用时会要求重新登陆!

(2)driver.background app(seconds)

四、Appium -元素定位

1.定位单个元素:

(1)ID定位:driver.find_element by_id(resource-id属性值)

(2)class定位:driver.find element by class name(class属性值)

(3)xpath定位:driver.find element by_xpath(xpath表达式)

(4)name定位:driver.find element by accessibility id(content-desc属性值)

(5)当定位到多个符合条件的元素时,默认返回第一个

2.定位一组元素

(1)使用定位一组元素时,返回的数据是列表

python 复制代码
from appium import webdriver

# Appium启动代码示例

#定义字典变量
desired_cap={}
# 构造配置项
desired_cap['platformName']='Android'
desired_cap['platformVersion']='12.0'
desired_cap['deviceName']='emulator-5556'
desired_cap['appPackage']='com.android.settings'
desired_cap['appActivity']='.Settings'

# 设置为中文
desired_cap['unicodeKeyboard']=True
desired_cap['resetKeyboard']=True

# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_cap)

五、元素操作-API

1.模拟操作

(1)模拟点击 element.click()

(2)模拟输入 element.send_keys(value)

(3)清除文本 element.clear()

2.获取元素信息-文本[断言时使用]、位置、大小

(1)获取文本 element.text

(2)获取位置: element.location

(3)获取大小: element.size

python 复制代码
from time import sleep

from appium import webdriver
from selenium.webdriver.common.by import By

# Appium启动代码示例

#定义字典变量
desired_cap={}
# 构造配置项
desired_cap['platformName']='Android'
desired_cap['platformVersion']='12.0'
desired_cap['deviceName']='emulator-5556'
desired_cap['appPackage']='com.android.settings'
desired_cap['appActivity']='.Settings'

# 设置为中文
desired_cap['unicodeKeyboard']=True
desired_cap['resetKeyboard']=True

# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_cap)
# 获取所有id 为:android:id/title
els=driver.find_elements(By.ID,'android:id/title')
# 遍历打印输出
for el in els:
    print(el.text)
sleep(3)
driver.quit()

3.获取元素属性值 ---用于判断是否为希望的元素

(1)获取属性值:element.get_attribute(属性名)

(2)获取属性值对应的属性名与实际工具(如Appium Inspector)显示可能不一致,如

获取resource-id属性值,el.get_attribute('resourceId')

获取content-desc,el.get_attribute('name')

获取class,el.get_attribute('className')

获取text,el.get_attribute('text')

python 复制代码
from time import sleep

from appium import webdriver
from selenium.webdriver.common.by import By

# Appium启动代码示例

#定义字典变量
desired_cap={}
# 构造配置项
desired_cap['platformName']='Android'
desired_cap['platformVersion']='12.0'
desired_cap['deviceName']='emulator-5556'
desired_cap['appPackage']='com.android.settings'
desired_cap['appActivity']='.Settings'

# 设置为中文
desired_cap['unicodeKeyboard']=True
desired_cap['resetKeyboard']=True

# 获取driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_cap)
# 获取所有id 为:android:id/title
els=driver.find_elements(By.ID,'android:id/title')
# 遍历打印输出
# for el in els:
#     print(el.text)
# sleep(3)

# 使用get_attribute获取这些元素的enable text content-desc ...
for el in els:
    print("1.enabled属性值为:",el.get_attribute('enabled'))
    print("2.text属性值为:",el.get_attribute('text'))
    print("3.content-desc属性值为:",el.get_attribute('name'))
    print("4.resource-id属性值为:",el.get_attribute('resourceId'))
    print("5.class属性值为:",el.get_attribute('className'))
    print("-----------------------------------------")
driver.quit()

六、手势滑动

1.滑动和拖拽设置

2.swipe滑动[原生应用 -如]:

(1)从一个坐标位置滑动到另一个主表为止,只能是两个点之间的滑动

(2)driver.swipe(start_x, start y, end x, end _y, duration=None)

start x:start y:起点Y轴坐标

end x:终点X轴坐标

end y:终点Y轴坐标

duration:滑动这个操作一共持续的时间长度,单位:ms

3.滑动[WebView --如浏览器]:

TouchAction(driver).press(x=start_x, y=start_y).wait(ms=1000).move_to(x=end_x, y=end_y).release().perform()

4.Scoll滑动

(1)从一个元素滑动到另一个元素,直到页面自动停止

(2)driver.scroll(origin el,destination el)

origin el:滑动开始的元素

destination el:滑动结束的元素

(3)scroll滑动是两个元素之间的滑动只适合滑动一次的操作

惯性很大

七、手势API

1.TouchAction

(1)创建TouchAction对象

touch_action=TouchAction(driver)

(2)调用高级手势对象所提供的手势方法

touch_action.手势方法

(3)执行手势

touch_action_perform()

!! (4)!所有手势都要通过执行perform()函数才会运行

2.TouchAction-轻敲(类似于点击)

(1)模拟手指对某个元素或坐标按下并快速抬起

(2)实现:元素对象或坐标二选一

touch_action.tap(element=....).perform()

touch_action.tap(x=...,y=...).perform()

python 复制代码
from time import sleep

from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.by import By

from driver_util import AppiumClient
import warnings
# 忽略DeprecationWarning类型的警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
# 调用示例
client = AppiumClient('com.android.settings', '.Settings')
driver = client.start_driver()
# 业务操作...

"""
    手势操作:TouchAction类
    1.轻敲:tap()
    需求:wifi设置
"""
# 1.轻敲
wlan=driver.find_element(By.XPATH,"//android.widget.TextView[@resource-id='android:id/title' and @text='网络和互联网']")
TouchAction(driver).tap(wlan).perform()
sleep(3)

client.quit_driver()

3.为什么要使用手势操作?

红包雨、九宫格解锁,需要手动操作,之前学习的api最多支持两个元素之间或两个坐标之间进行操作

4.TouchAction-按下和抬起

(1)模拟手指一直按下,模拟手指抬起。可以用来组合轻敲或长按是操作

(2)实现:元素对象或坐标二选一

touch_action.press(el=...)perform()

touch_action.release(x=...,y=...)perform()

TouchAction(driver).press(x=loc.get('x'),y=loc.get('y')).release().perform()

python 复制代码
from platform import release
from time import sleep

from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.by import By

from driver_util import AppiumClient
import warnings
# 忽略DeprecationWarning类型的警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
# 调用示例
client = AppiumClient('com.android.settings', '.Settings')
driver = client.start_driver()
# 业务操作...

"""
    手势操作:TouchAction类
    1.轻敲:tap()
    需求:wifi设置
"""
# 1.轻敲
wlan=driver.find_element(By.XPATH,"//android.widget.TextView[@resource-id='android:id/title' and @text='网络和互联网']")
loc=wlan.location
print(loc)
sleep(3)
# 2.按下和抬起 --效果类似点击
TouchAction(driver).press(x=loc.get('x'),y=loc.get('y')).release().perform()
sleep(3)
client.quit_driver()

5.TouchAction-长按--有个时间

(1)模拟手指对元素或坐标的长按操作

(2)实现:元素或坐标二选一

TouchAction(driver).long_press(el=...,duration=1000).perform()

(3)场景:有些长按和点击出现的菜单不一样;有些是只有长按才出现菜单

6.移动和等待 move_to(x,y) wait()

python 复制代码
from platform import release
from time import sleep

from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.by import By

from driver_util import AppiumClient
import warnings
# 忽略DeprecationWarning类型的警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
# 调用示例
client = AppiumClient('com.android.settings', '.Settings')
driver = client.start_driver()
# 业务操作...


# 长按
driver.find_element(By.XPATH,"//android.widget.TextView[@resource-id='android:id/title' and @text='网络和互联网']").click()
sleep(3)

# 3.长按
el=driver.find_element(By.XPATH,"//android.widget.TextView[@resource-id='android:id/title' and @text='互联网']").click()
TouchAction(driver).long_press(x=300,y=700,duration=5).perform()
sleep(3)
client.quit_driver()
相关推荐
Wpa.wk14 小时前
接口自动化 - 接口组合业务练习(CRUD组合)-REST-assure(Java版)
java·运维·经验分享·测试工具·自动化·接口自动化
Lethehong14 小时前
TextIn 赋能!Dify+DeepSeek 高效搭建新能源汽车销量可视化工作流
大数据·前端·python·textin·蓝耘元生代·蓝耘maas
亿元程序员14 小时前
爆款拆解与实现:动态画出物理线条,手把手教你制作“画线救狗”
前端
weixin_5316518114 小时前
File.stream() 与 FormData 技术详解
开发语言·前端·javascript
TDengine (老段)14 小时前
TDengine JAVA 语言连接器入门指南
java·大数据·开发语言·数据库·python·时序数据库·tdengine
Allen_LVyingbo14 小时前
医疗AI多智能体协同路径规划(Cooperative Multi-Agent Path Finding)技术综述(上)
人工智能·python·算法·知识图谱·健康医疗
彩色面团儿14 小时前
Pycharm部署pytest运行测试(测试笔记一)
python·pycharm·集成测试·pytest
董世昌4114 小时前
如何声明一个类?类如何继承?
java·开发语言·前端
love530love14 小时前
EPGF 新手教程 04一个项目一个环境:PyCharm 是如何帮你“自动隔离”的?(全 GUI,新手零命令)
运维·开发语言·ide·人工智能·python·pycharm