利用Robotinum对给的apk文件进行自动化测试,在不知道源码的情况下,只有apk文件如何进行自动化测试呢?

  首先需要对apk文件进行重签名,并获得该apk文件的包名和程序入口的类名。

  最开始网上说用re-sign.jar这个jar包,但是我用mac电脑实验了很多次都不行,一直提示JAVA_HOME环境变量没有设置,可是我已经设置了,echo $PATH输出也能看到JAVA_HOME,不过在Windows系统上实验是好的,可惜我是mac电脑,实验了好几个小时都不行,特别是在真心实意的请教测试的小姑娘帮忙,但是小姑娘不鸟我的情况下,于是一怒之下就自己实现了re-sign.jar的功能。

  通过在Windows上看到的情况,re-sign.jar做了哪些事呢?首先是对已有的apk进行重签名,然后是获得该apk文件的包名和程序入口的类名,为了获得apk文件的包名和入口类名我们需要用到apktool这个工具,因为有些apk是做了混淆的,需要反编译才能得到清晰的AndroidManifest.xml文件。我们知道apk的包名是有这样的标示的: package="xxxxxx",而程序入口类名就是<activity > </activity>标签中包含<xxx.action.MAIN>和<category.LAUCNCH>的部分。这样通过解析Manifest.xml文件,就能获得包名和入口类名了。

  注意:其中需要配置JAVA环境变量,Android环境变量,还需要将apktool所在目录加入到环境变量。该shell脚本需要与apk在同级目录下

  开始动手写shell 脚本。

#!/bin/bash

# Program :
# re-sign to specialy apk
# History :
# 2015.9.4 evilking First release

echo ===============================
echo 1.将此.sh文件放置您需要签名的apk同级目录下
echo 2.传入FILE_NAME参数,并设置为需要签名的apk文件名
echo 3.设置ANDROID_TOOLS_PATH 环境变量 为sdk下的tools路径
echo 4.设置JDK/bin 环境变量
echo 5.需要将/Users/你的用户名/.android/debug.keystore复制到apk同级目录下
echo 5.此脚本是基于JDK1.6来签名的,如果之前的apk不是用此版本签名可能会出血“无法对jar进行签名”的情况,用ZIP工具打开,找到下面的目录META-INF,删除目录
echo 6.如果出现未提供-tsa或-tsacert的警告,签名指令后加上-tsa https://timestamp.geotrust.com/tsa
echo ===============================

#获得当前路径
Cur_Dir=$(pwd)

#需要签名的apk文件名
FILE_NAME=$1

#验证该apk文件是否存在
if [ ! -e ${FILE_NAME}.apk ];then
  echo "error: not fount ${FILE_NAME}.apk file"
  exit 1
fi

#查看指定apk的签名信息
echo 查看指定apk的签名信息
jarsigner -verify -verbose -certs ${Cur_Dir}/${FILE_NAME}.apk | tail -n 10

#删除掉apk中的签名信息
echo =================================
echo 开始删掉apk中的签名信息
mv ${FILE_NAME}.apk ${FILE_NAME}.zip

#从zip包中直接删除META-INF文件夹
zip -d ${FILE_NAME}.zip META-INF/*

mv ${FILE_NAME}.zip ${FILE_NAME}.apk

echo 删除META-INF完成
echo =================================
#将原来的apk修改回来

#再次查看_unsign.apk签名信息
echo =================================
echo 再次查看_unsign.apk的签名信息
jarsigner -verify -verbose -certs ${FILE_NAME}.apk | tail -n 10

#对apk包重新签名
echo =================================
echo 对.apk包重新签名

#检测debug.keystore是否在本目录下
if [ ! -e debug.keystore ];then
  echo "warning:re-sign need username/.android/debug.keystore file"
  read -p "input your uname : " uname
  cp /Users/${uname}/.android/debug.keystore ./debug.keystore
fi

jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore debug.keystore -storepass android -keypass android ${FILE_NAME}.apk androiddebugkey -tsa https://timestamp.geotrust.com/tsa


echo ==================================
echo =========签名成功......开始简化......

zipalign 4 ${FILE_NAME}.apk ${FILE_NAME}_sign.apk
echo ============简化签名完成============

#查看重新签名的apk信息
echo ===================================
echo ======查看重新签名后的apk信息==========
jarsigner -verify -verbose -certs ${FILE_NAME}_sign.apk | tail -n 10

rm ${FILE_NAME}.apk

#下面部分是提取该应用的包名和程序入口类名
echo =======================================
echo ================开始提取包名=============

apktool d ${FILE_NAME}_sign.apk &>/dev/null

echo =============提取包名=================

package_name=$(egrep "package=\".*\"" ${FILE_NAME}_sign/AndroidManifest.xml | sed 's/.*package=//g')
echo "package=$package_name"

#获取程序入口
echo =============获取程序入口================
declare -i last_line
last_line=$(grep -n "action.MAIN" ${FILE_NAME}_sign/AndroidManifest.xml | cut -d ':' -f 1)

declare -i first_line
first_line=$(cat ${FILE_NAME}_sign/AndroidManifest.xml | head -n ${last_line} | egrep -n "<activity" | cut -d ':' -f 1 | tail -n 1)

echo "程序入口类为:"
entry_class=$(head -n $last_line ${FILE_NAME}_sign/AndroidManifest.xml | tail -n +$first_line | sed 's/.*android:name=\"//g' | cut -d "\"" -f 1 |   head -n 1)
if [ "$(echo $entry_class | cut -d "." -f 1)" == "" ];then
  echo "$(echo $package_name | sed 's/"//g')$entry_class"
else
  echo "$entry_class"
fi

rm -r ${FILE_NAME}_sign/
echo ===================结束=============

 

   整整花了一天的时间,不过值了,久违的成就感啊。

 

  参考博文:http://blog.csdn.net/h5q8n2e7/article/details/47837653