测试环境准备
硬件环境
- 手机:真机或模拟器(可以Android Studio工具创建模拟器,也可以用第三方模拟器如网易木木)
- 电脑:Android手机可以用Windows/Mac,ios手机只能用Mac
软件环境
- java环境 参考连接
- node.js 官网下载,直接安装
查看是否安装成功:npm -v 或 node -v
用于安装appium server - python环境 官网下载,直接安装,配置环境变量
用于安装appium客户端 - Android Studio工具 官网下载,直接安装
用于安装Adroid SDK、创建android模拟器 - Android SDK ,安装教程
查看是否安装成功:adb version
常用的adb命令就在这里面 - Appium Inspector 官网下载,直接安装
用于定位app页面元素 - appium server
安装方式:npm install appium@1.19.1 -g
查看是否安装成功 : appium -v 有版本号
启动appium server后,它会监听本地4723端口,只要往这个端口发送请求,它会接收这个请求,并把它解析成手机端执行的指令。 - appium 客户端
安装方式:pip install appium-python-client
提供编写自动化测试脚本api
测试流程
该流程的执行环境为:win10操作系统+木木模拟器(android6) + python3.10.1 + appium1.19.1 + Appium-Python-Client2.2.0
- 启动木木浏览器,安装测试app(.apk文件),安装方式有3:
- 模拟器右下角 ”更多“ - ”安装“
- 命令行 adb install [apk路径,可以直接把.apk文件拖拽到这里]
- 代码自动化安装
# 实现 APP 的安装
driver.install_app('/Users/johndoe/path/to/app.apk')
# 检测 APP 是否被安装
driver.is_app_installed('com.example.AppName');
- 连接模拟器(cmd):
- 连接木木模拟器:adb connect 127.0.0.1:7555
- 连接android studio自带模拟器,无需连接。
- 连接真机,数据线连接手机并且开启usb调试模式。
验证连接成功(cmd):adb devices
- 启动appium server(cmd): appium 回车
- pycharm编写测试用例,运行。
编写测试用例流程
1. 定义caps字典,存储app相关信息
caps = {}
caps["platformName"] = "Android"
caps["deviceName"] = "simulator"
caps["appPackage"] = "com.xueqiu.android"
caps["appActivity"] = ".view.WelcomeActivityAlias"
caps["noReset"] = "true"
2. 定义包含caps里面的信息的driver
self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
# app启动比较慢,添加隐式等待
self.driver.implicitly_wait(10)
备注:
a. Remote方法会自动启动应用,进入首页。
b. 由于启动driver比较耗时,当执行多条用例时,不用每条case都重新定义一次driver,可以把定义driver的代码挪到setup_class(), 启动应用采用driver.lauch()方法。driver.lauch()是热启动,会进入到app的首页。
3.编写测试用例步骤(定位,交互,断言)
def test_input(self):
el1 = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "OS")
el1.click()
el2 = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Morse Code")
el2.click()
4. 退出app,回收session
self.driver.quit()
代码优化
进行PO封装,实现功能复用
框架优化(自动关闭弹窗,关键数据比如日志和截图记录,数据驱动等)
appium常用api
设备交互相关api
…待续
driver相关api
定义回收driver
# 定义driver
driver=webdriver.Remote('http://localhost:4723/wd/hub',caps)
# 销毁driver
driver.quit()
wait相关Api
# 隐式等待10秒
self.driver.implicitly_wait(10)
元素定位Api
# ACCESSIBILITY_ID 定位
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "OS")
# ID 定位
driver.find_element(AppiumBy.ID,"com.xueqiu.android:id/search_input_text")
# XPATH 定位
driver.find_element(AppiumBy.XPATH,"//*[@resource-id='com.xueqiu.android:id/code' and @text='BABA']")
应用相关Api
# 安装应用
driver.install_app("/path/xxxx.apk")
# 检查应用是否安装
driver.is_app_installed("package")
# 卸载应用
driver.remove_app("package")
# 启动应用
driver.start_activity("package","activity")
# 启动应用2
driver.launch_app()
# 关闭应用
driver.close_app()
# 重置应用
driver.reset()
# 把当前应用放到app后台
driver.background_app()
# 获得activity
driver.current_activity
文件操作相关api
# 从设备拉出文件:下载
driver.pull_file("path/filename")
# 向设备推送文件:上传
driver.push_file("path")
app页面元素相关api
动作事件
# 点击、清空内容、输入
ele = driver.find_element(AppiumBy.XPATH,"//*[@text='Grid']")
ele.click()
ele.clear()
ele.sendkeys()
属性获取
# 定位元素
ele = driver.find_element(AppiumBy.XPATH,"//*[@text='Grid']")
# 获取文本属性值
ele.text
# 获取指定属性值
ele.get_attribute("clickble")
# 获取位置属性值,返回{"y": 19,"x": 498},左上角的坐标
ele.location
# 获取大小属性值,返回{”width“:200,”height“:50}
ele.size
# 是否可见,返回bool
ele.is_enabled()
# 是否可用,返回bool
ele.is_displayed()
# 是否被选中,返回bool
ele.is_selected()
swip 滑屏事件
"""简单方式 driver.swipe(startX,startY,endX,endY,time)"""
driver.swipe(500,800,500,200,100)
"""适用各种分辨率方式 """
size = driver.get_window_size()
width = size.get("width")
height = size.get("height")
start_x = width / 2
start_y = height * 0.8
end_x = start_x
end_y = height * 0.3
duration = 2000
driver.swipe(start_x, start_y, end_x, end_y, duration)
TouchAction 事件
# 实例化action,传参driver
action = TouchAction(driver)
# 按下,,参数可以是元素也可以是坐标,press()方法一般和release()方法成对使用
ele = driver.find_element(AppiumBy.XPATH,"//*[@text='Grid']")
action.press(el=ele)
# 按下2
action.press(x=100, y=30)
# 释放
action.release()
# 长按,参数可以是元素也可以是坐标
action.long_press(el=ele)
# 点击,参数可以是元素也可以是坐标
action.tap(x=10,y=20)
# 移动,参数可以是元素也可以是坐标
action.move_to(el=ele)
# 暂停1秒
action.wait(1000)
"""实例代码"""
action = TouchAction(self.driver)
width = self.driver.get_window_size().get("width")
height = self.driver.get_window_size().get("height")
start_x = width * 0.5
start_y = height * 0.8
end_x = start_x
end_y = height * 0.2
ele = self.driver.find_element(AppiumBy.XPATH,"//*[@text='Grid']")
action.press(x=start_x, y=start_y).wait(1000).move_to(x=end_x, y=end_y).wait(1000).release().perform()
keyevent键盘事件
"""常用键盘编号
返回键:4
搜索键:84
回车键:66
退格键:67
"""
driver.keyevent(4)
driver.keyevent(66)
toast事件
toast_text = self.driver.find_element(AppiumBy.XPATH,"//*[@class='android.widget.Toast']").text
# toast_text = self.driver.find_element(AppiumBy.XPATH,"//*[@text='Clicked popup menu item Search']").text