1. 安装node.js v12.13.0.
cnpm淘宝镜像配置 :npm install -g cnpm --registry=https://registry.npm.taobao.org
appium,基于node.js实现,用于测试android、ios、混合应用、移动网页应用
cnpm install -g appium@1.7.2 : 安装appium
where appium: appium 安装路径
appium : 查看版本号 Appium v1.17.0
2. appium客户端
Appium-windows-1.15.1.exe: widnows客户端 [ 封装了node.js 和 appium, 不用装node.js appium ]
python 环境 安装
D:\software\ruanjinag\Python37\Scripts: 如果安装了配置环境变量即可,pip路径
pip install Appium-Python-Client: 使用pip安装python-appium模块
安装路径:D:\software\ruanjinag\Python37\Lib\site-packages\appium
是否安装成功:
1. >>> from appium import webdriver
2. pip list: Appium-Python-Client 0.52 查看是否有
注意:如果有2套python环境, 使用Python3,那么命令, python3、pip3
3.jdk 安装:
JAVA_HOME C:\Program Files\Java\jdk1.8.0_111
CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一点)
Path %JAVA_HOME%\bin
4.ANDROID_HOME:D:\softpackage\Java\android-sdk-windows6
path: %ANDROID_HOME%\platform-tools;
%ANDROID_HOME%\tools;
看环境是否安装好:
cnpm install appium-doctor -g
appium-doctor
原理:
Appium-Python-Client -> Appium-windows-1.15.1.exe启动 appium Server -> 移动设备(Android|IOS)
===================================Mac环境下配置====================================
Mac下环境配置:
sdk: /Users/denganzhi/Library/Android/sdk
cd ~
touch .bash_profile
open .bash_profile
export ANDROID_HOME=/Users/denganzhi/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
source .bash_profile
echo $PATH
=========================================================================
2. adb 命令使用0.adb 原理 :
widnows adb 客户端 ---> adb 服务器
↓
手机: adb daemon【守护进程】
1. 获取当前应用程序 包名|启动Activity
Mac/Linux:
adb shell dumpsys window windows | grep mFocusedApp
Windows:
adb shell dumpsys window windows | findstr mFocusedApp
# 获取当前正在运行APP的 包名/运行Activity名
mFocusedApp=AppWindowToken{feb4edd token=Token{967a2b4 ActivityRecord{ca1387 u0 com.android.dialer/.BBKTwelveKeyDialer t55}}}
2. 上传文件到手机
adb push python.txt /sdcard: push widnows python.txt到 手机sd卡下
3. 获取App 启动时间
启动原理App:
系统分配内存、 启动Application、 启动Activity
adb shell am start -W com.android.dialer/.BBKTwelveKeyDialer
ThisTime: 169: BBKTwelveKeyDialer Activity运行时间
TotalTime: 169 Application运行时间+ Activity运行时间
WaitTime: 185 系统分配内存时间+ Application运行时间 + Activity运行时间
4. adb logcat
adb logcat *:e :显示error级别日志
adb logcat *:e > cat.log
https://www.cnblogs.com/bydzhangxiaowei/p/8168598.html : adb 日志 过滤
adb install xx.apk
adb uninstall 包名
adb devices: 但是adb 连接设备列表
adb kill-server: 停止adb
adb start-server: 启动adb 服务端
adb --help: 查看帮助
1. 启动app
2. 启动其他app
3. 关闭app
4. 安装 卸载app
5. 应用进入到后台 5s, 在回到前台
启动Android 设置界面:
import time
from appium import webdriver # 导入Appium-Python-Client 框架库
#### 1. 启动应用 -- appium 的 helloworld
desired_caps = dict()
desired_caps['platformName']='Android' # 系统
desired_caps['platformVersion']='6.0.0' # 手机号
desired_caps['deviceName']='127.0.0.1:5555'
desired_caps['appPackage']='com.android.settings' # 启动应用包名
desired_caps['appActivity']='.Settings' # 指定activity
driver= webdriver.Remote("http://127.0.0.1:4723/wd/hub",desired_caps)
#客户端连接appium服务器
time.sleep(5) # 等待 3S
# 2. 从一个应用 跳转到 另外一个应用
#driver.start_activity("com.soaic.basecomponent",".activity.ServiceDemoActivity")
# 3. 关闭app, 获取当前应用包名|activity名
#driver.close_app()
# 输出当前应用的包名和界面名
print(driver.current_package)
print(driver.current_activity)
# 4. 安装 卸载app
# if driver.is_app_installed("com.kaidishi.lock"):
# driver.remove_app("com.kaidishi.lock")
# else:
# driver.install_app("E:/app.apk")
# 5. 应用进入到后台 5s, 在回到前台
driver.background_app(5)
driver.quit() # driver 直接退出,运行终止,driver就是一个管家,手指
6. 元素定位
UIAutomatorViewer: 一款可视化手机界面工具
android-sdk-windows6\tools\bin\uiautomatorviewer.bat
元素定位: 通过id、 class 、 xpath
6.1. 根据上面三个特征,定位到一个元素
6.2. 定位到一组元素
7. 元素等待
网络没有返回html标签,控件还没有被渲染,那么使用元素等待
不在这个页面
分类:
隐士等待:
显示等待:
8. 元素操作api
8.1. 点击元素 element.click()
8.2. EditText文本框, 输入和清空内容
8.3. 获取文本内容 .text、位置、大小
8.4. 根据属性名获取属性值
9. 滑动和拖拽事件
9.1. 使用swiper 滑动屏幕
9.2 scroll滑动事件, 参数,元素,从一个元素滑动到另外一个元素 有惯性
9.3 drag_drop, 拖拽替换,第二个元素替换第一个元素,没有惯性
10. 高级手势TouchAction
10.1 手指轻敲( 就是按下、抬起组合),和点击差不多
10.2 按下和抬起
10.3 等待: 按下 等待 抬起, 模拟长按下,长按是不用抬起触发
10.4 长按2s ,等价于 TouchAction(driver).press(save_btn).wait(2000).release().perform()
10.5 移动操作, 案例解锁手机图案
11. 手机操作API
11.1 获取手机的宽度、高度
12.1 获取手机截图, 参数 写路径
13.1 获取设置手机网络
14. 发送键到设备
15. 操作手机通知栏
import time
from appium import webdriver
#### 启动应用
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.wait import WebDriverWait
desired_caps = dict()
desired_caps['platformName']='Android'
desired_caps['platformVersion']='6.0.0'
desired_caps['deviceName']='127.0.0.1:5555'
desired_caps['appPackage']='com.android.settings'
desired_caps['appActivity']='.Settings'
driver= webdriver.Remote("http://127.0.0.1:4723/wd/hub",desired_caps)
# 6. 元素定位
# 原理: 通过 UIAutomatorViewer 可以把所有的元素都遍历一遍
# 如何定位一个元素,模拟按钮点击search按钮
# 通过元素id, 通过 UIAutomatorViewer 找到 Resource Id
# 如果id 不唯一,有多个多个控件,返回的是第一个控件,那么通过xpath表达式不同点来定位
search_btn=driver.find_element_by_id("com.android.settings:id/search")
# 点击搜索
search_btn.click()
# 定位输入框,通过全类名,并且输入hello
# 如果有2个,找到的是第一个
driver.find_element_by_class_name("android.widget.EditText").send_keys("hello")
# 使用xpath定位返回按钮,通过context-des属性,xpath可以通过任意属性,点击返回按钮
driver.find_element_by_xpath("//*[@content-desc='搜索设置']").click()
# 如何定位一组元素,返回的是一个数组
# id可以重复,通过 UIAutomatorViewer使用
titles=driver.find_elements_by_id("com.android.settings:id/title")
print(len(titles))
for title in titles:
print(title.text)
# 通过全类名获取所有元素
textviews= driver.find_elements_by_class_name("android.widget.TextView")
print(len(textviews))
for textview in textviews:
print(textview.text)
# 包含内容 text '设'
xpaths= driver.find_elements_by_xpath("//*[contains(@text,'设')]")
for xpath in xpaths:
print(xpath.text)
#注意:
# find_element_by_id 如果id 不存在,报错 NoSuchElementException
# find_elements_by_id 如果I不存在,那么返回[]
# 7.1 隐式等待,针对所有元素 定位
# app 测试案例,现在在A 页面, 元素在B 页面,
# 设置隐式等待10s,那么 在10 s 跳入B 页面,找到了了元素,显示
# 如果超过10S, 还没有找到 元素,报错 NoSuchElementException
driver.implicitly_wait(10)
xpath1= driver.find_element_by_xpath("//*[contains(@text,'设')]")
# 有效果
xpath2= driver.find_element_by_xpath("//*[contains(@text,'设')]")
# 7.2. 显示等待 ,不会阻塞代码
# 针对单个元素,在 25s , 每隔5s 调用一次 x.find_element_by_xpath,如果不写5,默认是0.5s
# 找到了,返回元素,没有找到继续找
wait = WebDriverWait(driver,25,5)
back_button=wait.until(lambda x: x.find_element_by_xpath("//*[contains(@text,'设')]"))
print(back_button.text)
# 报错,上面只是针对当个元素
xpath3 = driver.find_element_by_xpath("//*[contains(@text,'设')]")
# 8. 元素 操作Api
# 8.1. 点击元素 element.click()
# 8.2. EditText文本框, 输入和清空内容
# send_keys("hello") 输入内容
# clear 清空内容
# 默认输入中文无效,设置如下
desired_caps['unicodeKeyboard']=True
desired_caps['resetKeyboard']=True
# 8.3. 获取文本内容 .text
# 获取元素 位置和 大小
# element.location, {x,y} 坐标
# element.size {height,width} 宽度、高度
# 8.4 根据属性名获取属性值
# 获取文本内容
search_btn.text();
# 获取属性值
search_btn.get_attribute("enabled") # 控件是否可用
search_btn.get_attribute("text")
# 特殊
search_btn.get_attribute("resourceId") #必须把resource_Id中间_去掉
search_btn.get_attribute("ClassName") # 必须把class 改成 ClassName
search_btn.get_attribute("name") #获取content-desct通过name
# 9. 滑动和拖拽事件
# 9.1. 使用swiper 滑动屏幕
# driver.swiper(起始x坐标,起始y坐标,结束的x坐标,结束y坐标,持续时间ms)
# 从下往上滑动
driver.swipe(100,600,100,100)
# 持续时间是 5s
driver.swipe(100,600,100,100,5000)
# 滑动特点:
# 特点:参数坐标点,
# 持续时间短, 惯性大
# 持续时间长 惯性小
# 滑动为什么有误差
# 计时器会计算时间在5S内,每隔开1S,都会去判断当前坐标,可能在这是cpu跑去干别的,造成误差
# 9.2 scroll滑动事件, 参数,元素,从一个元素滑动到另外一个元素 有惯性
# 开始位置 在下方向
# 应用在 更多的 下方
btn1=driver.find_element_by_xpath("//*[@text='应用']")
btn2= driver.find_element_by_xpath("//*[@text='更多']")
driver.scroll(btn1,btn2)
# 9.3 drag_drop, 拖拽替换,应用在下方,用应用替换更多
driver.drag_and_drop(btn1,btn2)
# 9.1 9.2 9.3实际工作中不需要惯性,用的是9.3
# 10. 高级手势TouchAction
# 轻敲、按下抬起、等待、长按、移动
# 10.1 手指轻敲( 就是按下、抬起组合),和点击差不多
# 使用步骤 1,2,3
# 创建TouchActio对象 调用想要执行动作 通过perform执行
# ** 参数可以传递对象, 点击 5次
TouchAction(driver).tap(save_btn,5).perform()
# ** 参数可以传递坐标
TouchAction(driver).tap(x=650,y=650).perform()
# 10.2 按下和抬起
# 点击事件: 按下、抬起, 如果只有按下,不能模拟点击时间
TouchAction(driver).press(save_btn).perform()
time.sleep(2)
TouchAction(driver).press(save_btn).release().perform()
# 10.3 等待: 按下 等待 抬起, 模拟长按下,长按是不用抬起触发
# TouchAction(driver).tap(save_btn).perform()
# time.sleep(3)
# TouchAction(driver).press(save_btn).wait(2000).release().perform()
# 10.4 长按2s ,等价于 TouchAction(driver).press(save_btn).wait(2000).release().perform()
# TouchAction(driver).long_press(save_btn,2000).perform()
# 10.5 移动操作, 案例解锁手机图案
# 进入设置中解锁页面
desired_caps['appPackage']='com.android.settings'
desired_caps['appActivity']='.ChooseLockPattern'
# move_to 方法,如何确定坐标,把鼠标放到手势的点上,会有提示
TouchAction(driver).press(x=79,y=290).move_to(x=239,y=452).move_to(x=239,y=290).move_to(x=400,y=290).release().perform()
# 11. 手机操作API
# 11.1 获取手机的宽度、高度
# driver.get_window_size()
# 12.1 获取手机截图, 参数 写路径
#driver.get_screenshot_as_file("screen.png")
# 13.1 获取设置手机网络
# Possible values:
# Value (Alias) | Data | Wifi | Airplane Mode
# -------------------------------------------------
# 0 (None) | 0 | 0 | 0
# 1 (Airplane Mode) | 0 | 0 | 1
# 2 (Wifi only) | 0 | 1 | 0
# 4 (Data only) | 1 | 0 | 0
# 6 (All network on) | 1 | 1 | 0 数据和wifi都打开
#print(driver.network_connection)
# 设置手机网络
#driver.set_network_connection(0) # 关闭数据、wifi
# 14. 发送键到设备
# android 按键列表:https://www.cnblogs.com/bluestorm/p/4886662.html
# 发送键都设备
# 三次 音量+ ,返回 + 2次音量 减
# driver.press_keycode(24)
# driver.press_keycode(24) # 音量+
# driver.press_keycode(4) # 返回键
# driver.press_keycode(25) # 音量-
# 15. 操作手机通知栏
# 拉下通知栏
# driver.open_notifications()
# 关闭通知栏,点击返回键
# driver.press_keycode(4)
time.sleep(50)
driver.quit()
获取手势坐标点,把鼠标放在手势点上,右上角显示坐标:
小置同学
原创文章 135获赞 149访问量 14万+
关注
私信
展开阅读全文
作者:小置同学