Appium介绍
Appium 是一个开源的自动化测试工具,支持 Android、iOS 平台上的原生应用,支持 Java、Python、PHP 等多种语言,开发可快速上手,用于提供各种手机事件模拟接口,通过编写代码模拟用户真实操作进行测试。Appium 封装了 Selenium,安卓自动化和web自动化语法上互通。
Appium环境
以下仅本人配置:
Ubuntu 22.04.1
jdk 11.0.19 (安装Android Studio的时候自动装的)
Python 3.10.6
Android SDK 34
PyCharm 2023.1.3
App自动化原理
如何通过代码操作不同操作系统不同版本的手机终端?
自动化脚本 —>> Appium Server —>> Android SDK 环境 —>> 被测手机终端
启动Appium Server,并通过adb连接手机
Python自动化脚本如何操作手机终端(Appium日志角度):
- 自动化脚本发送http请求,请求参数:终端设置的参数
- 创建会话
- 确认终端设备是否连接,并确定安卓版本,确认设置参数是否与终端的设置一样
- Appium会推送一个包 ‘AppiumBootsrap.jar’,模拟器上 api包:appium server指令今夕接受操控手机端(自测没有这个jar)
- 相应的http请求,如200或者500
常用adb 命令
adb shell ip route show table main # 查看路由表
adb shell cat /proc/net/dev|grep rmnet_data # 获得流量变化
adb shell cat /proc/net/dev|grep wlan0 # 获得wifi变化
adb shell ip -f inet addr # 查看手机数据方式
adb shell ifconfig # 可以查看网络类型和网速
常用python命令
driver.terminate_app(package_name) # 退出应用,防止干扰下一次操作
driver.current_package # 获取包名
driver.cirrent_activiry # 获取活动名
x_locate, y_locate = qqlive_driver.get_window_size()['width'], qqlive_driver.get_window_size()['height']
qqlive_driver.tap([(0.94 * x_locate, 0.092 * y_locate)]) # 点击
driver.implicitly_wait(5) # 隐式等待,5秒内查找到元素则执行,5秒后还没找到才报错
WebDriverWait(self.driver, 10).until(lambda x: x.find_element(by=AppiumBy.XPATH, value='//*[@text="通讯录"]')).click() # 显示等待
print(i.get_attribute("enabled")) # 通过id i获取控件属性值
print(i.get_attribute("clickable"))
print(i.get_attribute("text"))
print(i.get_attribute("resourceId")) # 返回resource-id,需API>=18
print(i.get_attribute("className")) # 返回class,需API>=18
print(i.get_attribute("name")) # 返回content-desc/text, 这个测试不生效
get_attribute('contentDescription') # 返回content-desc
# 有惯性传元素:scroll;无惯性传元素:drag_and_drop;
# 有惯性传坐标:swip; 无惯性传坐标:swipe & duration;
swipe(self, start_x: int, start_y: int, end_x: int, end_y: int, duration: int = 0) # 开始和结束的x,y值,还有区间时间
scroll(self, origin_el: WebElement, destination_el: WebElement, duration: Optional[int] = None) # 从一个元素,移动到另一元素,有惯性
drag_and_drop(self, origin_el: WebElement, destination_el: WebElement) # 从一个元素,移动到另一元素替换原元素位置
# 点击目标下一个元素
friend_start = self.driver.find_element(by=AppiumBy.XPATH, value='//*[@text="联系人"]').location
friend_end = self.driver.find_element(by=AppiumBy.XPATH, value='//*[@text="联系人"]').size
friend_start_new_y = friend_start['y'] + friend_end['height'] + 10
self.driver.tap([(friend_start['x'], friend_start_new_y)])
# python打印时间
milliseconds = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
time.time() # 当前时间秒数显示
print("测试", end="\n\n") # 打印“测试”,并空一个空行
print(f"测试{a}") # a是变量,假设a = Appium,打印“测试Appium”
print("耗时{:.2f}s!".format(a)) # a是变量,假设a = 1.11111,打印"耗时1.11s!"
常用代码
# numpy处理数组
rx_speed = [0, 0.1, 0.12, 3.12, 4.124, 3.223, 3.339, 0.45, 0.78, 0.43]
print(numpy.median(rx_speed)) # 求中位数:0.615
print(numpy.mean(rx_speed)) # 求平均值:1.5685999999999998
print(np.sum(rx_speed)) # 求和:15.685999999999998
print(max(rx_speed) / 4) # 最大值除以4: 1.031
print(np.array(rx_speed) > 0) # [False True True True True True True True True True]
print(np.extract(np.array(rx_speed) > 1, rx_speed)) # [3.12 4.124 3.223 3.339]
print(np.partition(rx_speed, -1)[-1]) # 最大值 4.124
print(np.partition(rx_speed, -2)[-2]) # 次大值 3.339
print(np.partition(rx_speed, 0)[0]) # 最小值 0.0
print(np.partition(rx_speed, 1)[1]) # 次小值 0.1
# 去掉所有0的列
np.delete(speed_up, np.argwhere(np.all(speed_up[..., :] == 0, axis=0)), axis=1).flatten()
# 保留和最大列
speed_down = speed_down[:, np.argmax(np.sum(speed_down, axis=0))]
def extract_info(string):
"""
分离字符串中的小数和字符,输入字符串12.3MB或者12MB,输出12.3和MB或者12和MB
:param string:字符串12.3MB
:return:(12.3, MB)
"""
match = re.search(r"(\d+\.\d+)([MB])", string)
if match:
number = float(match.group(1))
unit = match.group(2)
return number, unit
else:
match = re.search(r"(\d+)([MB])", string)
if match:
number = int(match.group(1))
unit = match.group(2)
return number, unit
else:
return None, None
def unifiedUnit(number, unit):
"""
统一单位为兆,如输入1GB,输出1024.MB
:param number:数量
:param unit:单位
:return:以MB结尾的数量
"""
match unit:
case "GB":
number = number * 1024
case "MB":
pass
case "KB":
number = number / 1024
return round(number, 3) # 保留三位小数
常用定位工具
https://github.com/appium/appium-inspector/releases
获取应用的包名和启动页
- 已经安装应用的话,直接打开应用输入以下命令(获取的Activity不一定是启动页):
adb shell dumpsys activity | grep mFocusedApp > com.netease.cloudmusic/.activity.MainActivity # 以网易云为例,包名/Activity名字\
- 使用aapt工具(有时候也不靠谱):
aapt dump badging '/home/xxx/software/安装包/安卓安装包/网易云音乐-8.10.80.apk' | grep package > package: name='com.netease.cloudmusic' versionCode='8010080' versionName='8.10.80' compileSdkVersion='34' compileSdkVersionCodename='14' aapt dump badging '/home/zhangtao/software/安装包/安卓安装包/网易云音乐-8.10.80.apk' |grep launchable-activity > launchable-activity: name='com.squareup.leakcanary.internal.DisplayLeakActivity' label='Leaks' icon='res/mipmap-anydpi-v26/a.xml'