当前位置: 代码迷 >> Android >> [android]android自动化测试十一之代码覆盖率汇报EMMA
  详细解决方案

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

热度:44   发布时间:2016-05-01 20:42:27.0
[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     * [email protected] FinishListener} that may have been provided using     * [email protected] #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     * [email protected] 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 [email protected] #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
  相关解决方案