zoukankan      html  css  js  c++  java
  • Robotium测试报告的生成方法(上)

    7.1 使用junit-report生成报告

       这个是参考网上的:http://www.xuebuyuan.com/2148574.html,经我个人验证是可行的方法,网上写的挺详细的,不过有些不太清楚明白的地方,鉴于网上说的有点迷茫,所以下面我再细化一下。

    (1)下载junit-report

    这个包是我们生成报告的基础,所以先下载这个包,下载地址如下:https://github.com/jsankey/android-junit-report

    (2)创建Robotium测试用例

    创建好我们的Robotium测试用例,并且根据需要组织好测试用例。现在我们测试用例是针对众筹网的,只有一个登录测试用例,如图7.1.1所示:

    7.1.1准备好测试用例

    (3)添加junit-report包到工程中

    将刚刚下载的android-junit-report-1.5.8.jar包,添加到项目中。通过右击项目—>”Build path”à”Configure build path…”,在打开的对话框中“Libraries”à”Add External JARs…”,将包附加进来。

    如图7.1.2所示:

    图7.1.2 添加junit-report包

    同时,选择“Order and Export”选项卡,将刚刚添加进来的包选择,单击“OK”按钮,完成包的添加。

     

    (4)修改AndroidManifest.xml文件

    修改AndroidManifest.xml文件如下,使用JUnitReportTestRunner运行测试用例。

    将下面两句:

     

           android:targetPackage="com.subject.zhongchou" />

    修改成:

     

           android:targetPackage="com.subject.zhongchou" />

    (5)修改Run Configurations配置

    当我们修改了xml文件后,还需要修改一下Run Configurations配置。右击项目,选择“Run as”à“Run Configurations…”,在打开的窗口中左侧的“Andriod JUnit Test”下选择要设置的项目,如“AllTests”。然后在右侧选择“Run all tests in the selected project or package”,单击“Instrumention runner”后面的下拉框,就可以看到我们在Xml文件中填写的“com.zutubi.android.junitreport.JUnitReportTestRunner”,然后单击“run”按钮,则测试用例就会在我们的测试机上运行起来。如图7.1.3所示:

    图7.1.3 配置RunConfiguration

    (6)查看测试报告

    经过上面的配置,通过JUnitReportTestRunner运行测试用例后,会在手机上/data/data/com.subject.zhongchou/files下生成测试报告文件junit-report.xml。如果你用的是其他的App,则com.subject.zhongchou会不同,找到你自己的App名称即可。如图7.1.4所示:

    图7.1.4 在手机上生成测试报告

    注:用junit-report在手机上生成报告是有一个前提的,你的手机必须已经Root,并且给/data/data文件夹设置了777权限。否则我们无法将测试报告写到系统数据文件夹下,也没有办法查看文件。

    (7)取出测试报告

    测试用例是在手机上运行的,所以产生的测试也在手机中。虽然我们可以直接用手机查看报告,可是还是不如在电脑上查看的方便。现在我们在测试工程中创建文件夹“test-output”,使用下面的命令将测试报告拉取到这个文件夹中:

    C:adb pull /data/data/com.subject.zhongchou/files/junit-report.xmlD: obotiumautotesthongChouDemo est-output

    然后在打开测试报告文件,内容如下:

    (8)总结

    这个junit-report是官方提供的包,使用起来比较方便。但是测试机必须先root。测试报告是Xml格式的,不方便阅读,网上说在jenkins中任务构建完成后即可使用Publish JUnit test result report插件分析得出单元测试报告。由于时间问题,我还没有尝试一下jenkins能否分析,不过后面我们会有自己的办法分析xml报告。 

    7.2使用testuntils生成报告

       Testunitilsjunit-report类似,也是借助于第三方的包,产生测试报告的,除了产生的测试报告文件名为TEST-all.xml外,使用步骤和产生报告的路径也完全一样。怎么说这也是另一种方法,多学习一点儿也没有坏处的同,下面我们讲解一下这个方法。

    1)下载testuntils

    当然在使用第三方的包之前,要下载对应的包。Testuntils包的下载地址是:http://code.google.com/p/nbandroid-utils/

    2)创建Robotium测试用例

    创建好我们的Robotium测试用例,并且根据需要组织好测试用例。同样我们使用上面创建的测试用例文件,结构如图7.1.1所示。

    3)添加Testuntils包到工程

    将刚刚下载的testutils.jar包,添加到项目中。通过右击项目—>”Build path”à”Configure build path…”,在打开的对话框中“Libraries”à”Add External JARs…”,将包附加进来。

    如图7.2.1所示:

    图7.2.1 添加testutils

    同时,选择“Order and Export”选项卡,将刚刚添加进来的包选择,单击“OK”按钮,完成包的添加。

    4)修改AndroidManifest.xml配置

    修改AndroidManifest.xml文件如下,使用testutils运行测试用例。

    将下面两句:

     

           android:targetPackage="com.subject.zhongchou" />

    修改成:

     

           android:targetPackage="com.subject.zhongchou" />

    (5)修改Run Configurations配置

    当我们修改了xml文件后,还需要修改一下Run Configurations配置。右击项目,选择“Run as”à“Run Configurations…”,在打开的窗口中左侧的“Andriod JUnit Test”下选择要设置的项目,如“AllTests”。然后在右侧选择“Run all tests in the selected project or package”,单击“Instrumention runner”后面的下拉框,就可以看到我们在Xml文件中填写的“com.neenbedankt.android.test.InstrumentationTestRunner”,然后单击“run”按钮,则测试用例就会在我们的测试机上运行起来。如图7.2.2所示:

    图7.2.2 配置RunConfiguration

    (6)查看测试报告

    经过上面的配置,通过InstrumentationTestRunner运行测试用例后,会在手机上/data/data/com.subject.zhongchou/files下生成测试报告文件TEST-all.xml。如果你用的是其他的App,则com.subject.zhongchou会不同,找到你自己的App名称即可。如图7.2.3所示: 

    图7.2.3 在手机上生成测试报告

    注:和junit-report一样,用Testuntils在手机上生成报告是有一个前提的,你的手机必须已经Root,并且给/data/data文件夹设置了777权限。否则我们无法将测试报告写到系统数据文件夹下,也没有办法查看文件。

    (7)取出测试报告

    测试用例是在手机上运行的,所以产生的测试也在手机中。虽然我们可以直接用手机查看报告,可是还是不如在电脑上查看的方便。现在我们在测试工程中创建文件夹“test-output”,使用下面的命令将测试报告拉取到这个文件夹中:

    C:adb pull /data/data/com.subject.zhongchou/files/TEST-all.xmlD: obotiumautotesthongChouDemo est-output

    然后在打开测试报告文件,内容如下:

    (8)总结

       TestuntilsJunit-report是完全一样的两个第三方包,只是生成的报告文件名不同,使用方法等都类似,它们之间的区别我没有深入去研究,不过使用这两个包都可以生成手机测试报告。

     

    7.3 重写InstrumentationTestRunner类生成报告

    由于Junit-reporttestuntils生成的报告都是在系统目录/data/data下面,如果手机没有Root,是没有权限生成报告的。所以我在网上看到了另一种方法,重写InstrumentationTestRunner类把报告生成到手机卡上,参考博客(http://blog.csdn.net/hunterno4/article/details/14485663)。下面我们也讲述一下这种方法:

    1)编写测试用例

         在我们执行测试用例之前,已经完成了测试用例工程和具体测试用例的编写,此时我们有公用的函数类和具体的测试用例文件,上面已经介绍过结构了,此处不再累述。

    2)编写InstrumentationTestRunner

    由于我们要重写InstrumentationTestRunner类,所以在我们的测试工程公共类中,如:/src/com/zhongchou/CommonFunctions路径下创建类文件InstrumentationTestRunner.java,内容如下:

    package com.zhongchou.CommonFunctions;  
      
    import java.io.File;  
      
    import java.io.FileWriter;  
      
    import java.io.IOException;  
      
    import java.io.Writer;  
      
       
      
    import org.xmlpull.v1.XmlPullParserFactory;  
      
    import org.xmlpull.v1.XmlSerializer;  
      
       
      
    import android.content.Context;  
      
    import android.os.Bundle;  
      
    import android.os.Environment;  
      
       
      
      
      
    publicclass InstrumentationTestRunnerextends android.test.InstrumentationTestRunner {  
      
        private Writer mWriter;  
      
        private XmlSerializer mTestSuiteSerializer;  
      
        privatelongmTestStarted;  
      
        privatestaticfinal String JUNIT_XML_FILE = "TEST-all.xml";  
      
          
      
          
      
        @Override  
      
        publicvoidonStart() {  
      
               try{  
      
                      FilefileRobo = new File(getTestResultDir(getTargetContext()));  
      
                      if(!fileRobo.exists()){  
      
                             fileRobo.mkdir();  
      
                      }  
      
                if(isSDCardAvaliable()){        
      
               FileresultFile = new File(getTestResultDir(getTargetContext()),JUNIT_XML_FILE);  
      
               startJUnitOutput(new FileWriter(resultFile));  
      
                }else{  
      
    startJUnitOutput(new FileWriter(new File(getTargetContext().getFilesDir(), JUNIT_XML_FILE)));  
      
                }              
      
            }  
      
            catch(IOException e){  
      
                thrownewRuntimeException(e);  
      
            }  
      
            super.onStart();  
      
        }  
      
       
      
        void startJUnitOutput(Writer writer) {  
      
            try {  
      
                mWriter = writer;  
      
                mTestSuiteSerializer = newSerializer(mWriter);  
      
                mTestSuiteSerializer.startDocument(nullnull);  
      
                mTestSuiteSerializer.startTag(null"testsuites");  
      
                mTestSuiteSerializer.startTag(null"testsuite");  
      
            } catch (Exception e) {  
      
                thrownewRuntimeException(e);  
      
            }  
      
        }  
      
          
      
          
      
           privatebooleanisSDCardAvaliable(){  
      
                  return Environment.getExternalStorageState()  
      
                                       .equals(Environment.MEDIA_MOUNTED);         
      
           }  
      
             
      
             
      
           private String getTestResultDir(Context context){  
      
               StringpackageName = "/" + "robotium";  
      
               Stringfilepath = context.getCacheDir().getPath() + packageName;  
      
                 
      
               if(android.os.Build.VERSION.SDK_INT < 8){  
      
                      if(isSDCardAvaliable()){  
      
                  filepath= Environment.getExternalStorageDirectory().getAbsolutePath()+packageName;  
      
                      }  
      
               }else{  
      
                      if(isSDCardAvaliable()){  
      
                  filepath= Environment.getExternalStorageDirectory().getAbsolutePath()+packageName;  
      
                      }  
      
               }            
      
            return filepath;  
      
        }  
      
          
      
        private XmlSerializer newSerializer(Writer writer) {  
      
            try {  
      
                XmlPullParserFactory pf =XmlPullParserFactory.newInstance();  
      
                XmlSerializer serializer =pf.newSerializer();  
      
                serializer.setOutput(writer);  
      
                return serializer;  
      
            } catch (Exception e) {  
      
                thrownewRuntimeException(e);  
      
            }         
      
        }  
      
          
      
        @Override  
      
        publicvoidsendStatus(int resultCode, Bundle results) {  
      
            super.sendStatus(resultCode, results);  
      
            switch (resultCode) {  
      
                caseREPORT_VALUE_RESULT_ERROR:  
      
                caseREPORT_VALUE_RESULT_FAILURE:  
      
                caseREPORT_VALUE_RESULT_OK:  
      
                try {  
      
                    recordTestResult(resultCode,results);  
      
                    } catch (IOException e) {  
      
                        thrownewRuntimeException(e);  
      
                    }  
      
                    break;  
      
                caseREPORT_VALUE_RESULT_START:  
      
                    recordTestStart(results);  
      
                default:  
      
                    break;  
      
            }  
      
        }  
      
          
      
        void recordTestStart(Bundle results) {  
      
            mTestStarted = System.currentTimeMillis();  
      
        }  
      
       
      
        void recordTestResult(int resultCode, Bundle results) throws IOException {  
      
            float time = (System.currentTimeMillis() - mTestStarted) / 1000.0f;  
      
            String className = results.getString(REPORT_KEY_NAME_CLASS);  
      
            String testMethod = results.getString(REPORT_KEY_NAME_TEST);  
      
            String stack = results.getString(REPORT_KEY_STACK);  
      
            int current = results.getInt(REPORT_KEY_NUM_CURRENT);  
      
            int total = results.getInt(REPORT_KEY_NUM_TOTAL);  
      
              
      
            mTestSuiteSerializer.startTag(null"testcase");  
      
            mTestSuiteSerializer.attribute(null"classname",className);  
      
            mTestSuiteSerializer.attribute(null"name",testMethod);  
      
              
      
            if (resultCode != REPORT_VALUE_RESULT_OK) {  
      
                mTestSuiteSerializer.startTag(null"failure");  
      
                if (stack != null) {  
      
                    String reason = stack.substring(0,stack.indexOf(' '));  
      
                    String message = "";  
      
                    int index = reason.indexOf(':');  
      
                    if (index > -1) {  
      
                        message =reason.substring(index+1);  
      
                        reason =reason.substring(0, index);  
      
                    }  
      
                    mTestSuiteSerializer.attribute(null"message",message);  
      
                    mTestSuiteSerializer.attribute(null"type",reason);  
      
                    mTestSuiteSerializer.text(stack);  
      
                }  
      
                mTestSuiteSerializer.endTag(null"failure");  
      
            } else {  
      
                mTestSuiteSerializer.attribute(null"time",String.format("%.3f", time));  
      
            }  
      
            mTestSuiteSerializer.endTag(null"testcase");          
      
            if (current == total) {  
      
                mTestSuiteSerializer.startTag(null"system-out");  
      
                mTestSuiteSerializer.endTag(null"system-out");  
      
                mTestSuiteSerializer.startTag(null"system-err");  
      
                mTestSuiteSerializer.endTag(null"system-err");  
      
                mTestSuiteSerializer.endTag(null"testsuite");  
      
                mTestSuiteSerializer.flush();  
      
            }  
      
        }  
      
       
      
        @Override  
      
        publicvoidfinish(int resultCode, Bundle results) {  
      
            endTestSuites();  
      
            super.finish(resultCode, results);  
      
        }  
      
       
      
        void endTestSuites() {  
      
            try {  
      
                mTestSuiteSerializer.endTag(null"testsuites");  
      
                mTestSuiteSerializer.endDocument();  
      
                mTestSuiteSerializer.flush();  
      
                mWriter.flush();  
      
                mWriter.close();  
      
            } catch (IOException e) {  
      
                thrownewRuntimeException(e);  
      
            }  
      
        }  
      
    }  

    代码是网上提供的,并且有相应的注释,在此就不讲解代码了。

    (3)修改AndroidManifest.xml配置

    修改AndroidManifest.xml文件如下,使用InstrumentationTestRunner运行测试用例。

    将下面两句:

     

           android:targetPackage="com.subject.zhongchou" />

    修改成:

     

           android:targetPackage="com.subject.zhongchou" />

    (4)修改Run Configurations配置

    当我们修改了xml文件后,还需要修改一下Run Configurations配置。右击项目,选择“Run as”à“Run Configurations…”,在打开的窗口中左侧的“Andriod JUnit Test”下选择要设置的项目,如“AllTests”。然后在右侧选择“Run all tests in the selected project or package”,单击“Instrumention runner”后面的下拉框,就可以看到我们在Xml文件中填写的“com.zhongchou.CommonFunctions.InstrumentationTestRunner”,然后单击“run”按钮,则测试用例就会在我们的测试机上运行起来。如图7.3.1所示:

    图7.3.1 配置RunConfiguration

    (5)查看测试报告

    经过上面的配置,通过我们重写后的InstrumentationTestRunner运行测试用例,会在手机上/sdcard/robotuim/下生成测试报告文件TEST-all.xml。如图7.3.2所示:

    图7.3.2 在手机上生成测试报告

    注:和前面的两种方法不同,此方法生成的测试报告在手机卡上,所以不需要Root手机,以设置权限等操作。

    (6)取出测试报告

    测试用例是在手机上运行的,所以产生的测试也在手机中。虽然我们可以直接用手机查看报告,可是还是不如在电脑上查看的方便。现在我们在测试工程中创建文件夹“test-output”,使用下面的命令将测试报告拉取到这个文件夹中:

    C:adbpull /sdcard/robotium/TEST-all.xml D: obotiumautotesthongChouDemo est-output

    然后在打开测试报告文件,内容如下:

    (7)总结

       经过重写InstrumentationTestRunner后,我们可以定义测试报告保存的位置,不需要对手机进行root和对系统文件进行权限设置。相对来说限制条件少了一些儿,当然有现成的代码,我们也不需要修改什么,如果你的编码能力还可以,可以根据自己的需要,重写上面的类。

    转自http://blog.csdn.net/dragonking0318/article/details/45478891
  • 相关阅读:
    sql-定义变量
    sql-逻辑循环while if
    iOS生命周期
    iOS系统架构
    SVN记住密码
    视图在控制权限的作用
    20140524数据库课笔记
    char和varchar区别
    多表查找
    create table约束
  • 原文地址:https://www.cnblogs.com/songzhenhua/p/9312785.html
Copyright © 2011-2022 走看看