获取工具
一、下载adb:
第一种方式:下载Android platform-tools,安装完成后运行,install下载tools工具 。打开“我的电脑”—》属性—》系统高级设置—》环境变量—》编辑Path变量,将Android platform-tools路径添加到系统环境变量里。
第二种方式:直接下载adb工具将文件地址 加入环境变量
检查是否安装成功:
win+r cmd 输入 adb 展示详细信息安装正确
二、关于adb 的命令:
1.adb devices , 获取设备列表及设备状态
2.adb shell am monitor:获取包名(打开想要获取包名的APP即可)
3.查看app启动页Activity
adb shell dumpsys window | findstr mCurrentFocus 命令,可以查看当前启动中的应用信息
打开app的时候启动该命令
![在这里插入图片描述](
3.1 同时查看包名和启动页activity 打开app的同时输入以下回车
adb shell dumpsys activity recents | find “intent={”
3.2 查看启动activity的时间(先stop,再start)
adb shell am start -S -W 包名/.SplashActivity
totaltime:APP从创建进程创建activity的时间(打开app响应的时间)ms
3.3 logcat查看日志
logcat 获取日志并导出
adb shell logcat --pid=20730 -f /mnt/sdcard/myLogcat.log #pid可以通过 adb shell top 查看 第一列是pid
adb pull /mnt/sdcard/myLogcat.log d:\test\ #导出到D盘test(不能直接导出到d盘,权限问题)
打开日志搜索CRASH(崩溃) 和ANR(超时)
pid的获取方式:
3.4 关闭app回到冷启动(未缓存广告和线程的状态)
adb shell am force-stop com.xxx.xxx
3.5 拆帧计算启动main线程时间,计算开屏广告加载时间,检查具体启动每个步骤要多少秒
3.5.1 录屏,将启动到启动结束的动作录下来,然后保存到电脑上
3.5.2 使用拆帧软件ffmpeg
安装:
bin目录添加到环境变量
测试是否安装成功:ffmpeg -version
3.6 进入到保存视频的文件夹下,cmd
>ffmpeg -i test.mp4 -r 10 framcs_%03d.jpg
-r : 1s拆成10帧
framcs_%03d :每一帧的名字拼接数字,不足3位的用0填充
通过计算点击到加载完成的帧数0.1 就是加载的秒数
如:从framcs_030 到 framcs_090 加载完成,就是600.1=6s
6s加载完成
这里可以分别通过数帧的方式,计算开屏动画和广告的s数
4.monkey命令
参考:
adb shell monkey -p 包名 -v 10000 >d:/ford.log
全屏,防止点击到状态栏:
adb shell settings put global policy_control immersive.full=*
取消全屏:
adb shell settings put global policy_control null
–throttle(毫秒)事件之间插入的固定延迟。通过这个选项可以减缓Monkey的执行速度。如果不指定,Monkey将尽可能快的产生并执行事件。
-s 用于指定伪随机数生成器的seed值,如果seed相同,则两次Monkey测试所产生的事件序列也相同的。
–ignore-crashes 忽略程序崩溃。设置此选项后,Monkey会执行完所有的事件,不会因crash而停止。
–ignore-timeouts 忽略程序无响应。设置此选项后,Monkey会执行完所有的事件,不会因ANR而停止。
–ignore-security-exceptions 忽略证书或认证异常。设置此选项后,Monkey会执行完所有的事件,不会因认证或证书异常而停止。
–ignore-native-crashes 监视系统中本地代码发生的崩溃
–monitor-native-crashes 忽略本地代码导致的崩溃。设置忽略后,Monkey将执行完所有的事件,不会因此停止。
-v -v –v 提供最详细的设置信息
5.appium python启动
启动appium程序
打开python:
引入一个包 appium-clent-agent
#coding=utf-8
from appium import webdriver
desired_caps = {
"platformName":"Android",
"platformVersion":"10.0.0",
"deviceName":"MQS7N19423008360",
"appPackage":"com.xx.xx",
"appActivity":"com.xxx.SplashActivity",
"automationName":"UiAutomator1",
"unicodeKeyboard":True,
"resetKeyboard":True,
"noReset":True
}
driver=webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
三、.appcrawler
1.下载appcrawler https://pan.baidu.com/s/1dE0JDCH!
2.启动appium
1.2确保adb devices 设备在线
2.命令行启动appcrawler:
2.1启动安装好了的app:
java -jar xxx.jar --capability “appPackage=包名,appActivity=启动页activity” -c xxxx.yml
2.2未安装程序启动app:
java -jar D:/xxxx.jar -a xxx.apk -c xxxt1.yml
2.3查看jar包所在文件夹中的测试文件夹 index.html
3.修改yml配置信息
---
pluginList: []
#是否截图
saveScreen: true
#报告title
reportTitle: "FORD_report_20211110"
resultDir: "FORD_report"
# 在执行操作后等待多少毫秒刷新
waitLoading: 500
waitLaunch: 500
# 结果报告是否展示没有遍历被取消的控件
showCancel: true
# 最大运行时间
maxTime: 5000
# 默认的最大深度10, 结合baseUrl可很好的控制遍历的范围
maxDepth: 10
# appium的capability通用配置
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
deviceName: "MQS7N19423008360"
appPackage: "com.xxx.xx"
appActivity: "com.xxx.xxx.SplashActivity"
automationName: "uiautomator1"
platformName: "Android"
testcase:
name: "TesterHome AppCrawler"
steps:
- given: []
when: null
then: []
xpath: "/*"
action: "Thread.sleep(5000)"
actions: []
times: 0
#定义了哪些控件应该要被遍历到
selectedList:
- given: []
when: null
then: []
# 发现按钮
xpath: "//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
#社区按钮 这个列表
xpath: "//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout[1]/android.view.View[1]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
# 商城按钮列表
xpath: "//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[4]/android.widget.FrameLayout[1]/android.view.View[1]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
# 我的
xpath: "//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[5]/android.widget.FrameLayout[1]/android.view.View[1]"
action: null
actions: []
times: 0
#哪些控件应该被先遍历
firstList: [
xpath: '//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]',
xpath: '//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]',
xpath: '//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[4]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]',
xpath: '//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[5]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]'
]
#哪些控件应该被最后遍历
lastList:
- given: []
when: null
then: []
xpath: ""
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//me.majiajie.pagerbottomtabstrip.internal.CustomItemLayout/android.widget.FrameLayout[3]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]"
action: null
actions: []
times: 0
backButton:
- given: []
when: null
then: []
xpath: ""
action: null
actions: []
times: 0
# 特定条件触发动作的设置
triggerActions:
# 手机号
- given: []
when: null
then: []
xpath: '//*[@resource-id="com.changanford.evos:id/et_login_mobile"]'
action: 11000001048
actions: []
times: 1
# 验证码
- given: [ ]
when: null
then: [ ]
xpath: '//*[@resource-id="com.changanford.evos:id/et_login_sms_code"]'
action: 123456
actions: [ ]
times: 1
#遇到以下xpath点击
- xpath: '//*[@resource-id="com.changanford.evos:id/cancel"]'
- xpath: '//*[@resource-id="com.changanford.evos:id/submit"]'
- xpath: '//*[@resource-id="com.android.permissioncontroller:id/permission_allow_button"]'
- xpath: '//*[@resource-id="com.android.permissioncontroller:id/permission_deny_button"]'
- xpath: '//*[@resource-id="com.changanford.evos:id/btn_login"]'
# 自动生成的xpath表达式里可以包含的匹配属性
xpathAttributes:
- "name"
- "label"
- "value"
- "resource-id"
- "content-desc"
- "instance"
- "text"
# 先按照深度depth排序,再按照list排序,最后按照selected排序。后排序是优先级别最高的
sortByAttribute:
- "depth"
- "list"
- "selected"
findBy: "default"
defineUrl: []
baseUrl: []
appWhiteList: []
urlBlackList: []
urlWhiteList: []
blackList:
- given: []
when: null
then: []
xpath: ".*[0-9]{2}.*"
action: null
actions: []
times: 0
beforeRestart: []
beforeElement:
- given: []
when: null
then: []
xpath: "/*"
action: "Thread.sleep(500)"
actions: []
times: 0
afterElement: []
afterPage: []
afterPageMax: 2
tagLimitMax: 2
tagLimit:
- given: []
when: null
then: []
xpath: "确定"
action: null
actions: []
times: 1000
- given: []
when: null
then: []
xpath: "取消"
action: null
actions: []
times: 1000
- given: []
when: null
then: []
xpath: ""
action: null
actions: []
times: 1000
assertGlobal: []