4、如何运行测试程序
  orange框架会生成一个jar包,当你配置好这些选项后,并且拿到了orange.jar后,直接运行命令
  java -jar Orange.jar D: \config.properties
  则orange框架会开始自动为测试应用以及被测应用重签名,按照配置项,创建、启动模拟器、安装apk文件、运行测试用例(crash自动重启模拟器,失败则自动重跑,当前多跑三次),测试用例运行完成后收集测试结果,发送到指定的收件人。
  Orange实现原理:
  1.1  自动重签名APK文件
  使用Robotium来测试应用的话,需要测试程序和被测程序的签名是一样的,但是一般被测程序都会有自己签名过,所以我们需要实现自动的删除被测程序以及测试程序的签名文件,然后使用统一的key对被测程序的测试程序进行签名。
  实现原理:
  1、删除apk文件中的META-INF文件夹
  使用winrar工具的 winrar d ***.apk META-INF 命令可以实现在不解压apk文件的情况下删除压缩包内指定文件夹
  所以这里需要先下载安装winrar工具,另外在电脑的环境变量中配置winrar的安装目录,保证在cmd命令中能够调用到winrar命令
  (PS:这里原来是使用的java jar -xvf 命令先把apk解压缩,然后调用删除方法删除掉META-INF,后使用jar -cvf压缩为apk文件,但是通过jar命令解压缩之后,重签名后的网易阅读apk会出现崩溃的情况,改成了通过winrar工具来实现)
  2、使用JARSIGNER命令对apk文件使用统一的key进行重签名操作
  3、使用zipalign命令对重签名后的文件进行优化
  Orange框架如何使用bat脚本:
  1、bat脚本和重签名的key在Orange的jar包中会保存一份
  2、运行Orange时,复制bat文件、key文件以及测试应用和被测试应用到temp目录下
  3、通过java方法的Process process = Runtime.getRuntime().exec( "cmd.exe /c start " + path); 执行bat文件
  4、bat文件会自动把当前目录下的apk文件全部都进行重签名,重签名的apk文件保存到指定目录下
  1.2  自动创建、启动、删除模拟器以及安装apk功能
  需要在不同sdk版本的模拟器上实现全自动切换运行测试用例,所以需要涉及到创建、启动、删除模拟器以及安装apk文件等功能。
  实现原理:
  所有这些操作都使用了android自带的android命令来实现的
  1、创建模拟器 android create avd --name OrangeAutoTest --target android-7 --force
  通过java中调用以上命令实现创建模拟器的操作,如何判断创建模拟器的是否成功,以及失败的话错误信息呢?
  Process process = Runtime.getRuntime().exec(cmd);来执行上面的cmd命令行
  然后通过process.getInputStream() 和process.getErrorStream()来获取到相应的返回信息,如果有错误信息的话可以再getErrorStream中获取到
  说明: 正确情况下getErrorStream能够获取到值的话则抛出异常说明命令执行是时候出错了,但是有些命令的话执行正常,但是getErrorStream也能获取到返回值,所以有些命令需要做特殊的处理。
  2、启动模拟器 emulator -avd OrangeAutoTest -sdcard  c:sdcard.img
  通过上面的命令启动模拟器,同时加载sdcard,sdcard可以通过mksdcard 20M c:sdcard.img命令来创建
  3、删除模拟器android delete avd -n OrangeAutoTest
  4、安装APK adb wait-for-device install -r *.apk
  1.3  Crash以及失败用例重跑功能
  平时我们使用Robotium编写完一些测试用例的时候经常是直接通过Eclipse运行多个测试用例,或者通过junit编写一个testsuite把需要运行的测试用例加入到testsuite中一次运行多个测试用例。
  但是在运行的过程中,我们会发现有时候应用会Crash,导致的结果是测试暂停,所有测试的结果都收集不到。
  另外在运行的时候因为模拟器的一些不稳定性,可能会存在某一次用例运行失败的情况,但是再次运行用例恢复正常了。
  为了解决Crash的问题,以及失败用例重跑的问题,我们开发了运行在PC端Orange框架。
  实现原理:
  1、运行测试用例的时候通过Orange框架控制每次只运行一个测试用例,这样子如果这一个用例运行crash了或者失败的话,我可以再次启动应用重新运行,对其它用例不会有影响。
  首先通过Robotium编写的需要运行的测试用例需要配置在xml文件中,按照类似TestNG配置文件的格式来指定这次运行哪些测试用例
<!-- packageName is required-->
<classes packageName="com.netease.mobile.autotest">
<class name="com.netease.mobile.autotest.testing.LoginTest">
<methods>
<include name="testLogin" />
<include name="testUnLogin" />
</methods>
</class>
</classes>
  这里要求配置的时候必须配置到具体的方法,我们运行的时候Orange框架会解析这个xml文件,后组合成以下的一些命令来循环运行测试用例,每次运行一个
  adb shell am instrument -e class com.netease.mobile.autotest.testing.LoginTest#testLogin -w com.netease.mobile.autotest/com.zutubi.android.junitreport.JUnitReportTestRunner
  adb shell am instrument -e class com.netease.mobile.autotest.testing.LoginTest#testUnLogin -w com.netease.mobile.autotest/com.zutubi.android.junitreport.JUnitReportTestRunner
  2、如何判断用例是运行Crash的?
  我们还是通过Process process = Runtime.getRuntime().exec(cmd);方法来运行第一步生成的adb命令,然后通过 process.getInputStream();获取到流的返回值,如果返回值中包含"shortMsg=Process crashed"字符的话,说明这个用例运行crash了,那我们使用重试机制
  再次运行这个测试用例,如果连续3次都是crash的话,则把crash的信息也写入到返回值中,保证了用例运行Crash的话也能够收集的错误信息。
  3、如果判断用例运行失败?
  这里使用了JUnitReportTestRunner的一个开源的插件(https://github.com/jsankey/android-junit-report),是重写了官方的InstrumentTestRunner,能够帮我们收集每个用例的执行情况。
  每次用例执行结束后,会在模拟器或者真机的指定位置下生成一个Junit-report.xml文件,我们通过adb pull 命令把这个文件保存到PC端,然后Orange框架来解析这个文件,如果结果中包含failure或者error的话说明这个用例运行失败了,则重跑用 例。
  如果不包含的话说明用例运行成功,则把刚才取出的xml文件存下来,后续所有用例运行完成整合为一个完整的xml结果文件。
  4、如何实现用例重跑?
  这个只需要实现一个方法的递归调用可以,每次运行的时候会查看返回值以及解析xml的返回结果文件,如果存在异常则递归调用该方法,同时会定义一个运行次数的参数,如果大于这个次数的时候不管是够通过都会保存当前后一次的运行结果。
//调用运行测试用例方法
result = e.run(testCase,   testAppPackageName);
// 如果出现timeout异常则再运行一次
if (result.equals(EmulatorHelper.timeOutException)) {
//如果超出运行次数,则保存错误信息,否则递归运行
if(j > runCount){
addErrorToXml(root,   testCase, "adb shell am timeoutexception",
beginTime,"TimeOutException");
return result;
}else{
return runTest(root, e, testCase,   testAppPackageName,appPackageName, j);
}