[android]android自动化测试十一之代码覆盖率报告EMMA

以下代码时监听测试程序结束后将Emma测试报告写入到虚拟机上,然后可以使用adb pull命令发送至硬盘上,这里需要测试程序集成Emma jar包,并需要修改ant build文件。

package com.example.instrumentation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.example.i2at.tc.TemperatureConverterActivity;
//import com.vladium.emma.rt.RT;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;

public class EmmaInstrumentation extends Instrumentation implements FinishListener {

    private static final String TAG = "EmmaInstrumentation";

    private static final boolean LOGD = true;

    private static final String DEFAULT_COVERAGE_FILE_PATH = "/mnt/sdcard/coverage.ec";

    private final Bundle mResults = new Bundle();

    private Intent mIntent;

    private boolean mCoverage = true;

    private String mCoverageFilePath;

    /**
     * Extends the AUT to provide the necessary behavior to invoke the
     * {@link FinishListener} that may have been provided using
     * {@link #setFinishListener(FinishListener)}.
     *
     * It's important to note that the original Activity has not been modified.
     * Also, the Activity must be declared in the
     * <code>AndroidManifest.xml</code> because it is started by an intent in
     * {@link EmmaInstrumentation#onStart()}. This turns more difficult to use
     * other methods like using template classes. This latter method could be
     * viable, but all Activity methods should be re-written to invoke the
     * template parameter class corresponding methods.
     *
     * @author diego
     *
     */
    public static class InstrumentedActivity extends
    TemperatureConverterActivity {
        private FinishListener mListener;

        public void setFinishListener(FinishListener listener) {
            mListener = listener;
        }

        @Override
        public void finish() {
            if (LOGD)
                Log.d(TAG + ".InstrumentedActivity", "finish()");
            super.finish();
            if (mListener != null) {
                mListener.onActivityFinished();
            }
        }

    }

    /**
     * Constructor
     */
    public EmmaInstrumentation() {

    }

    @Override
    public void onCreate(Bundle arguments) {
        if (LOGD)
            Log.d(TAG, "onCreate(" + arguments + ")");
        super.onCreate(arguments);

        if (arguments != null) {
            mCoverage = getBooleanArgument(arguments, "coverage");
            mCoverageFilePath = arguments.getString("coverageFile");
        }

        mIntent = new Intent(getTargetContext(), InstrumentedActivity.class);
        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        start();
    }

    @Override
    public void onStart() {
        if (LOGD)
            Log.d(TAG, "onStart()");
        super.onStart();

        Looper.prepare();
        InstrumentedActivity activity = (InstrumentedActivity) startActivitySync(mIntent);
        activity.setFinishListener(this);
    }

    private boolean getBooleanArgument(Bundle arguments, String tag) {
        String tagString = arguments.getString(tag);
        return tagString != null && Boolean.parseBoolean(tagString);
    }

    private void generateCoverageReport() {
        if (LOGD)
            Log.d(TAG, "generateCoverageReport()");

        java.io.File coverageFile = new java.io.File(getCoverageFilePath());

        // We may use this if we want to avoid refecltion and we include
        // emma.jar
        // RT.dumpCoverageData(coverageFile, false, false);

        // Use reflection to call emma dump coverage method, to avoid
        // always statically compiling against emma jar
        try {
            Class<?> emmaRTClass = Class.forName("com.vladium.emma.rt.RT");
            Method dumpCoverageMethod = emmaRTClass.getMethod(
                    "dumpCoverageData", coverageFile.getClass(), boolean.class,
                    boolean.class);
            dumpCoverageMethod.invoke(null, coverageFile, false, false);
        } catch (ClassNotFoundException e) {
            reportEmmaError("Is emma jar on classpath?", e);
        } catch (SecurityException e) {
            reportEmmaError(e);
        } catch (NoSuchMethodException e) {
            reportEmmaError(e);
        } catch (IllegalArgumentException e) {
            reportEmmaError(e);
        } catch (IllegalAccessException e) {
            reportEmmaError(e);
        } catch (InvocationTargetException e) {
            reportEmmaError(e);
        }
    }

    private String getCoverageFilePath() {
        if (mCoverageFilePath == null) {
            return DEFAULT_COVERAGE_FILE_PATH;
        } else {
            return mCoverageFilePath;
        }
    }

    private void reportEmmaError(Exception e) {
        reportEmmaError("", e);
    }

    private void reportEmmaError(String hint, Exception e) {
        String msg = "Failed to generate emma coverage. " + hint;
        Log.e(TAG, msg, e);
        mResults.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "\nError: "
                + msg);
    }

    /* (non-Javadoc)
     * @see com.example.instrumentation.FinishListener#onActivityFinished()
     */
    @Override
    public void onActivityFinished() {
        if (LOGD)
            Log.d(TAG, "onActivityFinished()");
        if (mCoverage) {
            generateCoverageReport();
        }
        finish(Activity.RESULT_OK, mResults);
    }

}

定义finish接口 

package com.example.instrumentation;

/**
 * Listen for an Activity to finish and invokes {@link #onActivityFinished()} when this happens.
 *
 * @author diego
 *
 */
public interface FinishListener {

        /**
         * Invoked when the Activity finishes.
         */
        void onActivityFinished();

}

修改ant build.xml文件

 <!-- It only instruments class files, not any external libs -->
            <emma enabled="true">
               <instr verbosity="${verbosity}"
                               mode="overwrite"
                               instrpath="${out.absolute.dir}/classes"
                               outdir="${out.absolute.dir}/classes">
                    <!-- DTM: 2011-12-23: added filter for R -->
                     <filter excludes="*.R" />
                     <filter excludes="*.R$*" />
                </instr>
                <!-- TODO: exclusion filters on R*.class and allowing custom exclusion from
                             user defined file -->
</emma>

https://wiki.jenkins-ci.org/display/JENKINS/Building+an+Android+app+and+test+project 
http://dtmilano.blogspot.com/search/label/android

时间: 2024-12-21 00:17:19

[android]android自动化测试十一之代码覆盖率报告EMMA的相关文章

[android]android自动化测试十之单元测试实例

android源代码中每个app下中都自带了一个test用例,下面主要介绍下camra单元测试用例  在AndroidManifest.xml中标明了测试用例instrumentation函数入口  Java代码 <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2008 The Android Open Source Project Licensed under the Apach

十一月Android系统版本占比调查报告

每月一次的Android系统版本占比调查报告又来了,像ClockWork一样,谷歌再一次更新了 Android平台各版本占比的数据,虽然相比上个月的54.2%有所下降,但是Gingerbread依然坚挺的守住了饼图中接近51%,Jelly Bean也由上个月的4%上升至6.7%.和以往一样,饼图显示了每个Android版本的增长和下降,不过这次谷歌将一些相似的版本归为了一类,比如4.0.x版本统一归为Ice Cream Sandwich中.如果想看完整的统计数据请点击下面的链接.Android

十月Android系统版本占比调查报告

每月一次的Android系统版本占比调查报告再次出炉,在十月份中Gingerbread系统依然保持着54%的占有率,而Jelly Bean系统则略微上涨2.7%,仅比九月份增加了0.9%.Gingerbread与Jelly Bean系统的数字令我们再次失望,相比九月份二者的占有率变化都不足1%,希望传说中即将到来的更新可以帮助我们改变这些数字.Android系统其它版本依然按照预定的轨迹变化,Ice Cream Sandwich由23.7%上升至25.8%,Honeycomb基本与上月保持一致,

关于Android发送短信获取送达报告的问题(推荐)

最近公司开发一个项目,要求app能够发送短信并获取送达报告.这本不是一个什么难题,实现这一功能的代码一搜一大把,那么这么简单的一个问题,为什么我要在这里提出来呢?那是因为我在写代码的时候掉入了一个坑,而且这很可能发生在很多和我一样粗心的朋友身上.先给大家分享一下当初让我掉进坑里的代码: 咋一看,好像这段代码并没有什么问题,但是在测试的时候发现无论发送多少条短信,每次都只能获取第一条短息的送达报告!!这个问题当时困扰了我很久,感觉自己明明没有写错啊,为什么会出现这样莫名其妙的问题呢?思索无果之后,

效果-Android Android 拖拽拼图功能的实现!!急!!在线等!急!

问题描述 Android Android 拖拽拼图功能的实现!!急!!在线等!急! 我要的效果是 比如我在左边选择了第一个模版,然后我拖拽到右边工作区域,松开放下,然后我在去左边选择模版,比如我在选择第一个模版,又拖动右边,比如我我放在我第一个的左边,这是要注意了,这2个图片不能重叠在一起!!如果我觉得第二个没放好!我可以在点击让他消失,在去左边选择一个模版,拖过来拼在上下左右的位置!!! 小弟先谢过各位了!! 有实例代码最好!!给小弟思路小弟也感激不尽!! 解决方案 在电脑中处理不行吗? 解决

文档-android: android 中文件的备份问题

问题描述 android: android 中文件的备份问题 我想问一下,如果我的app 生成了几个文件,有办法压缩备份成一个新的文件吗.? 我看有.backup 后缀的文件,是怎么生成的呢? 谢谢..最好有API 或者文档什么的 解决方案 Android文件访问权限和路径问题Android 本地文件读取, 数据库文件备份android读SDCard中txt文件中文乱码问题 解决方案二: .backup是一些备份文件.总体说来 Android API Level 8及其以上Android系统提供

Android——Android lint工具项目资源清理详解_Android

Android--Android lint工具项目资源清理 最近维护的项目已经有两年多,经过很多前辈的迭代,项目并没有变得健壮,而变得很臃肿.用Android lint工具清理了一次,清楚了不少废弃的布局和资源. 1.     Android lint工具 可以右键项目,Android tools,退出的时候clear lint markers即可 也可以如图: 2.结果出来了,分析分析 3.xml中view太多,已经超过了80个,影响性能. 布局优化: 尽量使用include.merge.Vi

[Android]Android端ORM框架——RapidORM(v2.0)

以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5626716.html [Android]Android端ORM框架--RapidORM(v2.0) RapidORM:Android端轻量高性能的ORM框架 GitHub: https://github.com/wangjiegulu/RapidORM 1. RapidORM v1.0 v1.0博客文档:http://www.cnblogs.com/tiant

[Android]Android端ORM框架——RapidORM(v2.1)

以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6020412.html [Android]Android端ORM框架--RapidORM(v2.1) RapidORM:Android端轻量高性能的ORM框架 GitHub: https://github.com/wangjiegulu/RapidORM RapidORM v2.1 feature 在执行SQL和创建表时提升性能. 提升bind参数时的性能 In