移动测试
1.概念
1.定义:测试手机程序。
2.测试方面:
- 功能测试:查看功能是否正常。
- 安装卸载测试
- 升级测试
- 兼容性测试:Android系统版本、厂商二次开发版本、不同的分辨率、不同的网络。
- 网络切换、中断测试
- 使用中来电、短信
- 横竖屏切换
- 健壮性:耗电量、流量消耗、崩溃恢复。
2. ADB
1.定义:Android Debug Bridge,既包含ADB服务,也包含与服务对应的Client。
2.作用:通过命令行去操作手机。
adb shell dumpsys window windows | findstr mFocusedApp
3.入门案例:等待5秒后关闭系统设置界面
步骤:打开模拟器系统设置页面 -> 启动appium -> 运行 demo01.py
from appium import webdriver
import time
# 连接移动设备所需参数
desired_caps = {}
# 当前要测试的设备名称
desired_caps["deviceName"] = "127.0.0.1:62001"
# 系统
desired_caps["platformName"] = "Android"
# 系统版本
desired_caps["platformVersion"] = "7.1"
# adb shell dumpsys window windows | findstr mFocusedApp
# 要启动的app的名称(唯一标识:包名)
desired_caps["appPackage"] = "com.android.settings"
# 要启动的app的哪个界面
desired_caps["appActivity"] = ".Settings"
# 连接手机
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
time.sleep(5)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
3.操作
基础API
①driver:
close_app()# 关闭打开的应用
quit()# 断开连接
install_app('apk在电脑上的绝对路径')# 安装应用
remove_app('应用的包名')# 卸载应用
is_app_installed('应用的包名')# 判断应用是否安装
push_file(目标位置,base64编码内容)
pull_file(来源位置)# 返回值是base64编码内容
page_source# 获取界面xml源码
find_element/find_elements
current_package# 获取当前操作的应用的包名
current_activity# 获取当前操作的界面的名称
②element:
text# 获取元素文本内容
click()# 点击元素对应位置
get_attribute(属性名称)# 获取属性值
location# 获取元素左上角的坐标(相对于屏幕左上角)
size# 获取元素的宽高(返回字典类型)
元素定位
Android SDK提供工具
可用于查找页面控件和鼠标位置。
from appium import webdriver
import time
# 连接移动设备所需参数
desired_caps = {}
# 当前要测试的设备名称
# adb devices
desired_caps["deviceName"] = "127.0.0.1:62001"
# 系统
desired_caps["platformName"] = "Android"
# 系统版本
# adb shell getprop ro.build.version.release
desired_caps["platformVersion"] = "7.1"
# adb shell dumpsys window windows | findstr mFocusedApp
# 要启动的app的名称(唯一标识:包名)
desired_caps["appPackage"] = "com.android.settings"
# 要启动的app的哪个界面
desired_caps["appActivity"] = ".Settings"
# 连接手机
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
# print(driver.page_source) 打印该页面所有资源
# 点击文本属性为显示的元素(注意:不是文本)
driver.find_element_by_xpath("//*[@text='显示']").click()
time.sleep(3)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
输入文本
send_keys("文本内容")
# 新版本不需要输入以下内容,可直接支持中文。若不支持时,可以在连接设备时加上以下配置
desired_caps['unicodeKeyboard'] = True# unicode设置
desired_caps['resetKeyboard'] = True# 键盘设置
clear()# 清除文本内容
from appium import webdriver
import time
# 连接移动设备所需参数
desired_caps = {}
# 当前要测试的设备名称
# adb devices
desired_caps["deviceName"] = "127.0.0.1:62001"
# 系统
desired_caps["platformName"] = "Android"
# 系统版本
# adb shell getprop ro.build.version.release
desired_caps["platformVersion"] = "7.1"
# adb shell dumpsys window windows | findstr mFocusedApp
# 要启动的app的名称(唯一标识:包名)
desired_caps["appPackage"] = "com.android.settings"
# 要启动的app的哪个界面
desired_caps["appActivity"] = ".Settings"
# 连接手机
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
time.sleep(1)
# 点击搜索框
driver.find_element_by_xpath("//*[@resource-id='com.android.settings:id/search']").click()
time.sleep(1)
driver.find_element_by_xpath("//*[@resource-id='android:id/search_src_text']").send_keys("abc")
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
模拟手势
滑动:
swipe(self, start_x: int, start_y: int, end_x: int, end_y: int, duration: int = 0)
duration默认600毫秒。滑动存在“惯性”,会根据按下、抬起位置及总时间,滚动不一样的距离。
滚动:
scroll(origin_el,destination_el,duration)
不需要手动获取位置,直接传递元素。手机的分辨率不会造成影响。
from appium import webdriver
import time
# 连接移动设备所需参数
desired_caps = {}
# 当前要测试的设备名称
# adb devices
desired_caps["deviceName"] = "127.0.0.1:62001"
# 系统
desired_caps["platformName"] = "Android"
# 系统版本
# adb shell getprop ro.build.version.release
desired_caps["platformVersion"] = "7.1"
# adb shell dumpsys window windows | findstr mFocusedApp
# 要启动的app的名称(唯一标识:包名)
desired_caps["appPackage"] = "com.android.settings"
# 要启动的app的哪个界面
desired_caps["appActivity"] = ".Settings"
# 连接手机
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
time.sleep(1)
# 滑动 driver.swipe(270, 640, 270, 320)
# 滚动
el1 = driver.find_element_by_xpath("//*[@text='通知']")
el2 = driver.find_element_by_xpath("//*[@text='WLAN']")
driver.scroll(el1, el2)
time.sleep(1)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
拖拽:
按下 -> 等待一定时间 -> 移动 -> 松手
drag_and_drop(origin_el,destination_el)
TouchAction:
比较复杂的、连续的触摸行为,如图案解锁屏幕。
创建TouchAction对象,传递driver参数 -> 添加动作 -> 执行操作perform()
press(self,el,x,y,pressure)# 按下,el和xy必须传递其中之一,pressure是ios专用
long_press(self,el,x,y,duration=1000)
move_to(self,el,x,y)# 移动
wait(self,ms)# 等待
release()# 松手
tap(self,el,x,y,count = 1)#轻敲/点击,count=2可以模拟双击
TouchAction 模拟滑动
from appium import webdriver
import time
from appium.webdriver.common.touch_action import TouchAction
# 连接移动设备所需参数
desired_caps = {}
# 当前要测试的设备名称
# adb devices
desired_caps["deviceName"] = "127.0.0.1:62001"
# 系统
desired_caps["platformName"] = "Android"
# 系统版本
# adb shell getprop ro.build.version.release
desired_caps["platformVersion"] = "7.1"
# 要启动的app的名称(唯一标识:包名)
desired_caps["appPackage"] = "com.android.settings"
# 要启动的app的哪个界面
desired_caps["appActivity"] = ".Settings"
# 连接手机
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
time.sleep(1)
# 实例化TouchAction 此处wait必不可少,wait(0)是使用默认600毫秒
action = TouchAction(driver)
action.press(driver.find_element_by_xpath("//*[@text='通知']")).wait(500).move_to(driver.find_element_by_xpath("//*[@text='WLAN']"))
action.release()
# 执行
action.perform()
time.sleep(1)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
设置解锁图案Z
# 滑动绘制解锁图案
from appium import webdriver
import time
from appium.webdriver.common.touch_action import TouchAction
# 连接移动设备所需参数
desired_caps = {}
# 当前要测试的设备名称
# adb devices
desired_caps["deviceName"] = "127.0.0.1:62001"
# 系统
desired_caps["platformName"] = "Android"
# 系统版本
# adb shell getprop ro.build.version.release
desired_caps["platformVersion"] = "7.1"
# adb shell dumpsys window windows | findstr mFocusedApp
# 要启动的app的名称(唯一标识:包名)
desired_caps["appPackage"] = "com.android.settings"
# 要启动的app的哪个界面
desired_caps["appActivity"] = ".Settings"
# 连接手机
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
time.sleep(1)
# 滑动界面到可以看到安全栏
action = TouchAction(driver)
action.press(driver.find_element_by_xpath("//*[@text='声音']")).wait(500)
action.move_to(driver.find_element_by_xpath("//*[@text='WLAN']"))
action.release()
action.perform()
time.sleep(1)
# 点击安全栏
driver.find_element_by_xpath("//*[@text='安全']").click()
time.sleep(1)
# 点击屏幕锁定栏
driver.find_element_by_xpath("//*[@text='屏幕锁定']").click()
time.sleep(1)
# 点击图案栏
driver.find_element_by_xpath("//*[@text='图案']").click()
time.sleep(1)
# 绘制解锁图案Z
action.press(x=105, y=450).wait(200)
action.move_to(x=270, y=450).wait(200)
action.move_to(x=435, y=450).wait(200)
action.move_to(x=270, y=615).wait(200)
action.move_to(x=105, y=780).wait(200)
action.move_to(x=270, y=780).wait(200)
action.move_to(x=435, y=780).wait(200)
action.release()
action.perform()
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
driver的其他操作
.device_time# 获取手机时间
.get_window_size()# 获取屏幕大小
.network_connection# 获取手机网络信息 1飞行模式 2wifi 4移动数据 6=2+4
.set_network_connection(数字)# 设置手机网络信息
.keyevent(按键数字)# 点击按键
.get_screenshot_as_file/save_screenshot(图片路径)# 截屏
.open_notifications()# 打开通知栏