最近一直在完成一些robotium的小功能,用来更方便的完成一些小功能的测试,或者可以说用来娱乐吧,幸得群内大神思路指点,就此引申,终于把这个功能得以实现

---------------将robotium脚本封装为APK,使用按钮控制用例运行覆盖程度,测试结果以简单的xml文件输入到手机SD卡目录下----------------------

废话不多说,转正题:

一、首先明确一点,这篇文章,是在你所编写的robotium脚本运行无异常的前提下实施

二、阐明思路:

1.我们需要一个运行良好的,逻辑正常的robotium工程

2.我们需要一个可以将脚本用例运行结果保存至本地的方法

3.我们需要一个activity,一个按钮,以及一个按钮点击事件去运行我们的robotium脚本

三、先介绍脚本用例运行结果的功能,我们都知道robotium用例的运行是依赖junit的Instrumentation的,所以,关于结果的输出,需要我们重写InstrumentationTestRunner类

  1 package baih;
  2
 3 import java.io.File;  4 import java.io.FileWriter;  5 import java.io.IOException;  6 import java.io.Writer;  7  8 import org.xmlpull.v1.XmlPullParserFactory;  9 import org.xmlpull.v1.XmlSerializer;  10  11 import android.content.Context;  12 import android.os.Bundle;  13 import android.os.Environment;  14  15 /**  16  * This test runner creates a TEST-all.xml in the files directory of the application under test. The output is compatible with that of the junitreport ant task, the format  17  * that is understood by Hudson. Currently this implementation does not implement the all aspects of the junitreport format, but enough for Hudson to parse the test results.  18 */  19 public class InstrumentationTestRunner extends android.test.InstrumentationTestRunner {  20 private Writer mWriter;  21 private XmlSerializer mTestSuiteSerializer;  22 private long mTestStarted;  23 private static final String JUNIT_XML_FILE = "TEST-all.xml";  24  25  26  @Override  27 public void onStart() {  28 try{  29 File fileRobo = new File(getTestResultDir(getTargetContext()));  30 if(!fileRobo.exists()){  31  fileRobo.mkdir();  32  }  33 if(isSDCardAvaliable()){  34 File resultFile = new File(getTestResultDir(getTargetContext()),JUNIT_XML_FILE);  35 startJUnitOutput(new FileWriter(resultFile));  36 }else{  37 startJUnitOutput(new FileWriter(new File(getTargetContext().getFilesDir(), JUNIT_XML_FILE)));  38  }  39  }  40 catch(IOException e){  41 throw new RuntimeException(e);  42  }  43 super.onStart();  44  }  45  46 void startJUnitOutput(Writer writer) {  47 try {  48 mWriter = writer;  49 mTestSuiteSerializer = newSerializer(mWriter);  50 mTestSuiteSerializer.startDocument(null, null);  51 mTestSuiteSerializer.startTag(null, "testsuites");  52 mTestSuiteSerializer.startTag(null, "testsuite");  53 } catch (Exception e) {  54 throw new RuntimeException(e);  55  }  56  }  57  58 /**  59  * 判断SD卡是否存在  60  * @return  61 */  62 private boolean isSDCardAvaliable(){  63 return Environment.getExternalStorageState()  64  .equals(Environment.MEDIA_MOUNTED);  65  }  66  67 /**  68  * 获取测试结果报告文件所在的路径  69  * @param context 被测工程的context  70  * @return 返回测试结果报告文件所在的路径  71 */  72 private String getTestResultDir(Context context){  73 String packageName = "/" + "robotium";  74 String filepath = context.getCacheDir().getPath() + packageName;  75  76 if(android.os.Build.VERSION.SDK_INT < 8){  77 if(isSDCardAvaliable()){ 78 filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ packageName; 79 } 80 }else{ 81 if(isSDCardAvaliable()){ 82 filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ packageName; 83 } 84 } 85 return filepath; 86 } 87 88 private XmlSerializer newSerializer(Writer writer) { 89 try { 90 XmlPullParserFactory pf = XmlPullParserFactory.newInstance(); 91 XmlSerializer serializer = pf.newSerializer(); 92 serializer.setOutput(writer); 93 return serializer; 94 } catch (Exception e) { 95 throw new RuntimeException(e); 96 } 97 } 98 99 @Override 100 public void sendStatus(int resultCode, Bundle results) { 101 super.sendStatus(resultCode, results); 102 switch (resultCode) { 103 case REPORT_VALUE_RESULT_ERROR: 104 case REPORT_VALUE_RESULT_FAILURE: 105 case REPORT_VALUE_RESULT_OK: 106 try { 107 recordTestResult(resultCode, results); 108 } catch (IOException e) { 109 throw new RuntimeException(e); 110 } 111 break; 112 case REPORT_VALUE_RESULT_START: 113 recordTestStart(results); 114 default: 115 break; 116 } 117 } 118 119 void recordTestStart(Bundle results) { 120 mTestStarted = System.currentTimeMillis(); 121 } 122 123 void recordTestResult(int resultCode, Bundle results) throws IOException { 124 float time = (System.currentTimeMillis() - mTestStarted) / 1000.0f; 125 String className = results.getString(REPORT_KEY_NAME_CLASS); 126 String testMethod = results.getString(REPORT_KEY_NAME_TEST); 127 String stack = results.getString(REPORT_KEY_STACK); 128 int current = results.getInt(REPORT_KEY_NUM_CURRENT); 129 int total = results.getInt(REPORT_KEY_NUM_TOTAL); 130 131 mTestSuiteSerializer.startTag(null, "testcase"); 132 mTestSuiteSerializer.attribute(null, "classname", className); 133 mTestSuiteSerializer.attribute(null, "name", testMethod); 134 135 if (resultCode != REPORT_VALUE_RESULT_OK) { 136 mTestSuiteSerializer.startTag(null, "failure"); 137 if (stack != null) { 138 String reason = stack.substring(0, stack.indexOf('\n')); 139 String message = ""; 140 int index = reason.indexOf(':'); 141 if (index > -1) { 142 message = reason.substring(index+1); 143 reason = reason.substring(0, index); 144 } 145 mTestSuiteSerializer.attribute(null, "message", message); 146 mTestSuiteSerializer.attribute(null, "type", reason); 147 mTestSuiteSerializer.text(stack); 148 } 149 mTestSuiteSerializer.endTag(null, "failure"); 150 } else { 151 mTestSuiteSerializer.attribute(null, "time", String.format("%.3f", time)); 152 } 153 mTestSuiteSerializer.endTag(null, "testcase"); 154 if (current == total) { 155 mTestSuiteSerializer.startTag(null, "system-out"); 156 mTestSuiteSerializer.endTag(null, "system-out"); 157 mTestSuiteSerializer.startTag(null, "system-err"); 158 mTestSuiteSerializer.endTag(null, "system-err"); 159 mTestSuiteSerializer.endTag(null, "testsuite"); 160 mTestSuiteSerializer.flush(); 161 } 162 } 163 164 @Override 165 public void finish(int resultCode, Bundle results) { 166 endTestSuites(); 167 super.finish(resultCode, results); 168 } 169 170 void endTestSuites() { 171 try { 172 mTestSuiteSerializer.endTag(null, "testsuites"); 173 mTestSuiteSerializer.endDocument(); 174 mTestSuiteSerializer.flush(); 175 mWriter.flush(); 176 mWriter.close(); 177 } catch (IOException e) { 178 throw new RuntimeException(e); 179 } 180 } 181 }

重 写InstrumentationTestRunner类后,需要在我们的测试工程下设置run Configurations,在你的测试工程上右键-移至Run As-run Configurations-android JUnit Test,更改你工程运行的Instrumentation runner,如果不更改,默认是android.test.InstrumentationTestRunner

红色框体圈住的位置需要更改为你重写的InstrumentationTestrunner路径

完成以上步骤后,你再运行robotium脚本,就会在你的手机根目录下名为robotium的文件夹中生成一个名为TEST-ALL.xml的文件,用来记录你的脚本运行结果,结构如下:

运行正常的结果,会显示运行时长,运行错误的用例,会打印错误信息,至于错误信息中的中文提示,是我用例中自己加的断言,各位可以自行斟酌

完成这一步,就可以实施我们的封装APK计划了。封装APK,第一,我们需要一个activity

界面比较挫,将就看。关于activity的创建和声明,请各位自行百度

activity中可以放置一个或多个按钮,由于robotium可以使用命令行进行启动运行,所以我们可以使用不同按钮的onclick事件来执行不同的脚本

如上:附上各种命令行启动命令:

运行所有测试用例:

adb shell am instrument -w packagename/InstrumentationTestRunnername

运行单个测试类或某个TestSuite
adb shell am instrument -e class packagename.testclassname -w packagename/InstrumentationTestRunnername

运行某个测试类里面的某个测试方法
adb shell am instrument -e class package名.测试类名#方法名 -w 工程名.package名/InstrumentationTestRunner class名

注意:请在编写代码前,在CMD中测试你所使用的命令是否可以正常运行

完成以上步骤后,我们可以将整个测试工程打包为APK文件,记得签名需要签debug签名,然后......安装到你的手机上,拔掉该死的数据线,点击按钮,开始自动虐你的手机吧:)

号外!号外!

由于手头上一直没有android level 17及以上版本的手机,有一个shell命令启动脚本的BUG,发生在SDK level 17及以上

API>=17中加入了INTERACT_ACROSS_USERS_FULL,目的在于允许不同用户的应用之间可以产生交互,了安全,因此在交互时会校验userSerialNumber,,发现用户标识不匹配,导致权限校验失败,就会产生startInstrumentation asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL的报错,导致脚本无法调用

群里尝试,发现在17及以上版本,命令中需要加入--user 0参数

adb shell am instrument --user 0 -w packagename/InstrumentationTestRunnername

可以在调用时使用Build.VERSION.SDK_INT<17来对当前版本做判断选择合适的命令行启动方式

转载于:https://www.cnblogs.com/cologne/p/3796408.html

robotium脚本封装为APK,实现脱离手机数据线,使用按钮点击控制用例运行的小功能...相关推荐

  1. [转载]robotium脚本封装为APK,实现脱离手机数据线,使用按钮点击控制用例

    原文地址:robotium脚本封装为APK,实现脱离手机数据线,使用按钮点击控制用例运行作者:机器,猫 最近一直在完成一些robotium的小功能,用来更方便的完成一些小功能的测试,或者可以说用来娱乐 ...

  2. Appium基础篇3-第一个appium自动化脚本之自动安装apk包到手机

    这篇,我们开始来一个实战练习,如何通过appium自动把电脑上一个安卓程序包给安装到一台安卓手机中.在写脚本之前,我们需要统一下方法和工具.我们知道Appium和selenium一样都支持Java和P ...

  3. appium自动化脚本之自动安装apk包到手机

    Appium基础篇3-第一个appium自动化脚本之自动安装apk包到手机 这篇,我们开始来一个实战练习,如何通过appium自动把电脑上一个安卓程序包给安装到一台安卓手机中.在写脚本之前,我们需要统 ...

  4. Tools_将Python脚本封装成exe可执行文件

    将Python脚本封装成exe可执行文件 将Python脚本封装成exe可执行文件 cx_freeze是用来将 Python 脚本封装成可执行程序的工具,支持最新的Python3.2版本.生成的执行文 ...

  5. java appium_Android应用开发之AS+Appium+Java+Win自动化测试之Appium的Java测试脚本封装(Android测试)...

    本文将带你了解Android应用开发AS+Appium+Java+Win自动化测试之Appium的Java测试脚本封装(Android测试),希望本文对大家学Android有所帮助. 一.为什么需要封 ...

  6. 数字人民币在上海试点,首次实现脱离手机的硬钱包支付模式!

    1月5日,数字人民币"硬件钱包"首次在上海开启测试.在上海交通大学医学院附属同仁医院员工食堂,一位医生通过邮储银行的"可视卡",借助数字人民币"硬件钱 ...

  7. 解决安卓apk在其他手机无法安装问题

    解决安卓apk在其他手机无法安装问题 问题截图 在其他手机安装apk显示安装失败返回-15代码 解决办法: 在gradle.propeities文件中的最下面添加一下代码 android.inject ...

  8. android 加固服务器,Python 脚本构建Android APK 自动加固、打渠道包并上传服务器

    Python 脚本构建Android APK 自动加固.打渠道包并上传服务器 常规流程 打出原始apk 使用乐固工具加固并打出响应渠道包 将生成的渠道包上传对应服务器,生成推广链接 因为每一步都需要人 ...

  9. Android Studio 无法安装apk到小米手机问题解决

    以前开发都是用自己的samsung手机,打开开发者选项和usb调试,直接可以连上Android Studio,进行调试,后来我的samsung退伍了,换上了Apple,就无法使用了,用公司的小米手机打 ...

最新文章

  1. 阮一峰老师的ES6入门:async 函数
  2. R语言ggplot2可视化:ggplot2可视化散点图并使用geom_mark_circle函数在数据簇或数据分组的数据点周围添加圆圈进行注释(自定义圆圈的大小)
  3. java model 中文乱码_Java解压zip 解决编码和中文乱码问题
  4. JSP项目_Web路径_磁盘物理路径
  5. 7.泡妞与设计模式(八)模板模式
  6. jdbc配置文件连接mysql_java jdbc使用配置文件连接数据库:
  7. Jenkins持续集成环境之插件管理和角色管理
  8. 在浏览器上浏览vue项目,后退按钮是可以正常返回上一页的,但打包成app后,点击手机上的物理返回按钮就直接退出app回到桌面...
  9. RabbitMQ(三) ——发布订阅
  10. 例子---PHP与Form表单之二
  11. Spring事物配置文件
  12. mysql之解决“mysql server has gone away“的问题
  13. web安全day4--DHCP部署与安全
  14. k8s api文档 调用heapster metrics
  15. matlab mysql数据库增删改查_ef6.0增删改查操作
  16. 华容道6×6图解_华容道(带图解)
  17. 气缸模组控制一以1200PLC为例从易到难学习
  18. 基于python、百度ocr、multiprocessing多进程、selenium网页自动化 、pyqt5界面弹出,实现发票的识别与对学校财务网站的脚本自动化上传操作的项目总结
  19. 常用app URL schemes
  20. 可以把JPG图片转成PDF的格式转换器

热门文章

  1. python的strftime函数_Python简单格式化时间的方法【strftime函数】
  2. 已知2019年是猪年,请在控制台输出从1949年到2019年中所有是猪年的年份
  3. ubuntu安装java依赖,在Ubuntu 16上安装R语言 - 未满足的依赖项
  4. 简易iframe-前端web网页设计(iframe标签运用)
  5. BWT算法解析及Java语言实现
  6. iOS仿QQ空间时间显示
  7. linux drwxr-xr-x 含义
  8. 3DMax和Maya到底哪个更牛B?这些你都知道吗?速看!
  9. 游戏建模:3DMax和Maya到底哪个更好用?
  10. 点云切片,并保存切片