app分类
- 原生app(使用和操作系统相同语言开发的程序,程序访问速度快,能够访问系统的一些程序:摄像机,wif)
- 混合app(webapp和原生app的组合)
- webapp(使用html5语言编写的一个程序,相当于内嵌了一个网页 (小程序))
app测试:稳定性测试(Monkey),appUI自动化测试(appium)
adt(android develop kit ) 安卓开发工具包
adb (android debug bridge) 安卓bug调试工具
avd(android virtual device) 安卓虚拟设备
adb 命令复习
- 连接模拟器 adb connect 127.0.0.1:21503
- 获取当前系统中连接的设备 adb devices
- 获取到包名的命令
- adb shell pm list packages
- adb shell dumpsys | find "mFocusedActivity" 可以获取到当前启动的包名和活动窗口名
- 通过uiautomator工具获取到包名
问题:对于monkey自动化测试过程中,遇到异常如何分析
- 首先,手动执行monkey执行的操作,查看是否存在异常
- 其次,使用种子数再次执行脚本,查看是否是因为环境不稳定导致的bug
- 再次:查看并分析日志报告,通过日志分析bug产生的原因
appium页面元素定位
- 使用id进行定位
- a=driver.find_elements_by_id('android:id/text1') #定位一组元素
a[2].click() #通过索引定位
- 使用class进行定位(定位一组元素,在通过索引操作)
- driver.find_element_by_class_name('android.widget.TextView').click()
- 使用xpath进行定位("//class属性值[@属性='属性值']")
- driver.find_element_by_xpath('//android.widget.TextView[@text="NFC"]').click()
- 使用android_uiautomator进行定位
- 使用text文本值进行定位
- new UiSelector().text("Text") 使用文本进行定位
- driver.find_element_by_android_uiautomator('new UiSelector().text("Text")')
- new UiSelector().textContains("Te") 使用部分文本进行定位
- new UiSelector().textStartsWith("Me") 使用以某个文本开头进行定位
- new UiSelector().textMatches("^A[a-z]{1}p$")' 以某个匹配规则进行定位
- .resourceId(),可以省略new UiSelector()
- driver.find_element_by_android_uiautomator('.resourceId("io.selendroid.testapp:id/my_text_field")')
- new UiSelector().text("Text") 使用文本进行定位
- 正则表达式的使用
- ^ 开头
- th$ 结尾
- {m} 匹配m次
- {m,} 匹配大于m次
- {m,n} 匹配大于m次,小于n次
- [abc] 匹配a,b,c
- [a-z] 匹配a...z
- 使用text文本值进行定位
from appium import webdriver
def init_driver():
"""
初始化driver
"""
desired_caps = {}
# 设备信息
desired_caps['platformName'] = 'Android'
desired_caps['deviceName'] = '5203af01ea37b499'
# 桌面的app信息
desired_caps['appPackage'] = 'com.xiaoma.launcher'
desired_caps['appActivity'] = '.ui.LauncherActivity'
# 中文输入允许
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
# 不清除应用数据
desired_caps['noReset'] = False
# 引入uiautomator2, 获取toast
desired_caps['automationName'] = 'uiautomator2'
# 修改超时时长, 默认是60秒
desired_caps['newCommandTimeout'] = 3600
# 声明我们的driver对象
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
return driver
切换上下文 (混合APP)
- print(driver.contexts) 获取当前系统所有的上下文
- 返回的值:['NATIVE_APP', 'WEBVIEW_com.android.launcher', 'WEBVIEW_io.selendroid.testapp']
- driver.switch_to.context(driver.contexts[1])
- 除了第一个NATIVE_APP不能选,其他都可以索引取
切换回 原生APP(native APP)
- driver.switch_to.context(driver.contexts[0])
弹窗的处理:直接元素定位,进行点击
前后台处理
- #让app在后台运行,4秒后再打开;若不想让它打开,就写-1
- driver.background_app(4)
driver.background_app(-1)
# 再重新调出后台运行的APP
driver.launch_app()
下拉框的处理
- 直接定位元素,进行click
self.driver.find_element_by_android_uiautomator('.resourceId("android:id/text1")').click()
self.driver.find_element_by_xpath('//android.widget.CheckedTextView[@index=%d]'% random.randint(0, 7)).click()
滚动条的处理
- 先定位到滚动条,通过size和location获得x/y轴,高和宽
e=self.driver.find_element_by_android_uiautomator('.resourceId("com.android.androidui:id/seekBar1")')
print(e.size)
print(e.location)
#滚动条至60%的位置
start_x = e.location['x']
start_y = e.location['y'] + e.size['height']/2
end_x = e.size['width']*0.6
end_y = e.location['y'] + e.size['height']/2
self.driver.swipe(start_x,start_y,end_x,end_y) #误差小
self.driver.flick(start_x,start_y,end_x,end_y) #误差稍大
self.driver.tap([(end_x,end_y)]) #直接滚动到指定位置
appium中九宫格的处理
from appium.webdriver.common.touch_action import TouchAction
TouchAction(self.driver).press(x=x,y=y).wait(3000).move_to(x=x1,y=y1).release().perform()
对于h5的页面元素定位的方式
- 将chrome的驱动器放置在C:\Program Files (x86)\Appium\resources\app\node_modules\appium-chromedriver\chromedriver\win
- pc端打开chrome浏览器,输入chrome://inspect/#devices,点击insepect,前提条件是app必须要是debug版本的
- 在测试中,开发给的包就是debug的,不用翻墙,直接打开Chrome浏览器,输入chrome://inspect/#devices,点击inspect