本帖最后由 悠悠小仙仙 于 2019-3-11 17:19 编辑
首先Appium运行,推送Bootstrap.jar到设备端,而Bootstrap.jar这个jar实际上就是继承了UiAutomatorTestCase的测试类,然后通过命令运行这个jar包开始执行自动化脚本 先来看看执行命令: - adb.exe -s 5b30ee87 shell uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap -e pkg com.main -e disableAndroidWatchers false
复制代码1.help 先通过uiautomator help看看命令 (1)help:帮助
(2)runtest:执行UI自动化测试
(3)dump:创建一个当前ui视图结构的xml文件
(4)events:打印accessibility事件
从帮助中可以看到uiautomator主要的4个命令,但是有个疑问又来了,uiautomator如何在android系统的手机设备中接收到这些并运行的。
2.uiautomator的shell脚本
在uiautomator源码的cmds文件夹中找到了uiautomator的shell文件,这个文件就是作为uiautomator初始化并启动执行的入口。 - export run_base=/data/local/tmp
- export base=/system
- # if not running as root, trick dalvik into using an alternative dex cache
- if [ ${USER_ID} -ne 0 ]; then
- tmp_cache=${run_base}/dalvik-cache
- if [ ! -d ${tmp_cache} ]; then
- mkdir -p ${tmp_cache}
- fi
- export ANDROID_DATA=${run_base}
- fi
复制代码(1)首先定义2个变量run_base、base,值都是设备的路径(再次提醒,这个uiautomator的shell文件是在android设备中运行,shell作为Linux的一部分,在Android设备中运行就没什么好说的,不理解的可以了解一下Android系统的组成)
(2)然后判断一下是否root用户运行:通过内部变量拿到用户ID,如果拿到的ID不是0,则执行语句块内容(root用户的ID为0,非root用户的ID不是0),下面的脚本就是确定一下数据存放地址。 - # take first parameter as the command
- cmd=${1}
- if [ -z "${1}" ]; then
- cmd="help"
- fi
- # strip the command parameter
- if [ -n "${1}" ]; then
- shift
- fi
- CLASSPATH=/system/framework/android.test.runner.jar:${base}/framework/uiautomator.jar
复制代码3)拿到第一个参数赋值给cmd变量,然后判断一下,如果第一个参数的值长度为0,则cmd值为help,从这里可以看到如果第一个参数没有值,肯定就是执行help的结果。
(4)再判断第一个参数的值不为空,则左移一个参数,这里需要特别注意,如果第一个参数有值,这里已经通过shift左移了一个参数 - # eventually args will be what get passed down to Java code
- args=
- # we also pass the list of jar files, so we can extract class names for tests
- # if they are not explicitly specified
- jars=
- # special case pre-processing for 'runtest' command
- if [ "${cmd}" == "runtest" ]; then
- # first parse the jar paths
- while [ true ]; do
- if [ -z "${1}" ]; then
- echo "Error: more parameters expected for runtest; please see usage for details"
- cmd="help"
- break
- fi
- jar=${1}
- if [ "${1:0:1}" = "-" ]; then
- # we are done with jars, starting with parameters now
- break
- fi
- # if relative path, append the default path prefix
- if [ "${1:0:1}" != "/" ]; then
- jar=${run_base}/${1}
- fi
- # about to add the file to class path, check if it's valid
- if [ ! -f ${jar} ]; then
- echo "Error: ${jar} does not exist"
- # force to print help message
- cmd="help"
- break
- fi
- jars=${jars}:${jar}
- # done processing current arg, moving on
- shift
- done
复制代码(5)如果第一个参数是runtest,cmd等于runtest,进入if语句块,然后开始循环判断,再次提醒上面已经shift左移一个参数,所以现在已经把runtest移走了,第一个参数是runtest后面的AppiumBootstrap.jar了。先判断第一个参数长度如为空,则又回到help输出让你多看看help的用法,用习惯命令的都知道,输错命令动不动就是显示help的结果。
(6)然后把第一个参数交给jar变量;进入判断,${1:0:1}的意思是取出${1}变量0到1的值,如果等于-,break回家再见;再往下不等于/,则jar=${run_base}/${1},根据上下文,jar的值得到是:/data/local/tmp/AppiumBootstrap.jar
(7)再次判断这个文件存不存在,不存在继续break回家再见;然后执行jars=${jars}: ${jar},jars的值为:/data/local/tmp/AppiumBootstrap.jar(冒号前面的${jars是空})。 - # look for --nohup: if found, consume it and trap SIG_HUP, otherwise just
- # append the arg to args
- while [ -n "${1}" ]; do
- if [ "${1}" = "--nohup" ]; then
- trap "" HUP
- shift
- else
- args="${args} ${1}"
- shift
- fi
- done
- else
- # if cmd is not 'runtest', just take the rest of the args
- args=${@}
- fi
复制代码(8)又一个循环,先判断${1}是否为空,不为空进入循环,如果参数等于--nohup,则忽略HUP信号,继续运行。可以回到上面看help帮助中的--nohub命令解释。(trap为捕捉信号,如HUP表示终端中断,INT键盘中断等等),并执行shift左移
(9)如果不等于nohup命令,取出参数值赋值给args变量。就算是命令中有--nohup,也只会进入一次if,其它都会进入else,直到取出的参数为空退出循环
(10)继续else语句块,这个else是对应上面cmd==runtest的else,也就是命令等于dump、events的时候进入,就没那么麻烦了,全部参数都复制给args - args="${cmd} ${args}"
- if [ -n "${jars}" ]; then
- args="${args} -e jars ${jars}"
- fi
- CLASSPATH=${CLASSPATH}:${jars}
- export CLASSPATH
- exec app_process ${base}/bin com.android.commands.uiautomator.Launcher ${args}
复制代码11)args的值${cmd} ${args},注意中间有个空格,然后进入一个判断,判断${jars}的值是否为空,而只有runtest的时候,才不会为空。所以runtest的时候,args的值:runtest -e jars ${jars},其他时候args的值都为${cmd} ${args}
(12)${CLASSPATH}: ${jars}处理后CLASSPATH的值:
/system/framework/android.test.runner.jar:/system/framework/uiautomator.jar::/data/local/tmp/AppiumBootstrap.jar
(13)export引入这些jar包,其中包含uiautomator.jar这个重量级的jar包。在uiautomator使用过程中,引入的是在本地引入,而在android设备中运行时,是从android中引入,所以在编写代码过程中一定要注意,编程环境用的版本需要小于等于运行环境的版本。
(14)通过app_process指定命令的工作路径为/system/bin,并运行com.android.commands.uiautomator.Launcher类传入的参数为${args}
|