Android Robotium黑盒测试封装为Apk

Android Robotium黑盒测试封装为Apk

如何在只有Apk的情况下进行测试?而且要写一个Android程序让被测试的app测试用例跑起来,然后再记录一些参数。使手机在脱离数据线的情况下尽情执行你的测试用例。没有头绪?不要着急,下面我们就来一步一步实现它。

一、准备工作
1.待测试apk文件
2.重签名工具re-sign
Android Robotium黑盒测试封装为Apk_第1张图片
re-sign下载链接
3.双击打开re-sign.jar,把apk文件拖入界面,重签名成功后会显示如下界面,保存packageName和MainActivity,以便以后使用。然后把重签名后的apk安装到手机上。
Android Robotium黑盒测试封装为Apk_第2张图片
4.布局查看工具Uiautomatorviewer:
一款非常好用的布局查看工具,环境配置好的前提下cmd粘贴uiautomatorviewer,回车即可打开。
Android Robotium黑盒测试封装为Apk_第3张图片

二、环境搭建
推荐环境变量配置(保证re-sign.jar成功运行):
Android Robotium黑盒测试封装为Apk_第4张图片

三、创建Android测试工程
a、创建Android Test Project
(1)File-New-Project-Android-Android Test Project
(2)输入工程名-next,选择This project-finish
b、创建Anroid testcase
使用uiautomatorviewer获取待测程序的布局,具体可将该工具的路径添加到环境变量中,或者进入该目录,用cmd运行,直接输入uiautomatorviewer就可以运行起来该工具,这是已经封装好的工具,可以直接用。。。
创建testcase的具体过程如下:
(1)工程名-src-包名-右击new-Junit Test Case
(2)在name一栏输入Test Case的名称
(3)Superclass一栏,选择android.test.ActivityInstrumentationTestCase2,点击finish
c、导入Robotium-jar包(需要注意和需要配置的项目)
通过建立lib文件夹,直接copy文件,需要在Build Path中进行配置。。。。具体步骤与下面添加report-jar包的步骤相同
(1)工程名-new-folder-lib
(2)直接将之前下载的robotium-solo-X.X.X.jar拷贝粘贴到lib目录下
(3)工程名-右击-Build Path-Configure Build Path-Libraries-Add External JARs
(4)点击右边的Order and Export,选择robotium-solo-X.X.X.jar的选项,点击OK
d、修改AndroidManifest.xml文件
该配置文件的修改主要包含增加节点

<instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="xxx.xxx.xxx" />

targetPackage与re-sign.jar中所获取到的包名相同,是指被测程序的包名
e、运行testcase
运行成功如下图所示
Android Robotium黑盒测试封装为Apk_第5张图片

四、修改为测试工程
在所编写的robotium脚本运行无异常的前提下,我们需要一个activity,一个按钮,以及一个按钮点击事件去运行我们的robotium脚本。
a、重写InstrumentationTestRunner类:
先介绍脚本用例运行结果的功能,我们都知道robotium用例的运行是依赖junit的Instrumentation的,所以,关于结果的输出,需要我们重写InstrumentationTestRunner类

package mytest;
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;


public class InstrumentationTestRunner extends android.test.InstrumentationTestRunner {
    private Writer mWriter;
    private XmlSerializer mTestSuiteSerializer;
    private long mTestStarted;
    private static final String JUNIT_XML_FILE = "TEST-all.xml";


    @Override
    public void onStart() {
        try{
            File fileRobo = new File(getTestResultDir(getTargetContext()));
            if(!fileRobo.exists()){
                fileRobo.mkdir();
            }
            if(isSDCardAvaliable()){   
                File resultFile = 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){
            throw new RuntimeException(e);
        }
        super.onStart();
    }

    void startJUnitOutput(Writer writer) {
        try {
            mWriter = writer;
            mTestSuiteSerializer = newSerializer(mWriter);
            mTestSuiteSerializer.startDocument(null, null);
            mTestSuiteSerializer.startTag(null, "testsuites");
            mTestSuiteSerializer.startTag(null, "testsuite");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    private boolean isSDCardAvaliable(){
        return Environment.getExternalStorageState()
                .equals(Environment.MEDIA_MOUNTED);   
    }


    private String getTestResultDir(Context context){
        String packageName = "/" + "robotium";
        String filepath = 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) {
            throw new RuntimeException(e);
        }       
    }

    @Override
    public void sendStatus(int resultCode, Bundle results) {
        super.sendStatus(resultCode, results);
        switch (resultCode) {
        case REPORT_VALUE_RESULT_ERROR:
        case REPORT_VALUE_RESULT_FAILURE:
        case REPORT_VALUE_RESULT_OK:
            try {
                recordTestResult(resultCode, results);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            break;
        case REPORT_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('\n'));
                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
    public void finish(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) {
            throw new RuntimeException(e);
        }
    }

b、设置run Configurations
重写InstrumentationTestRunner类后,需要在我们的测试工程下设置run Configurations,在你的测试工程上右键-移至Run As-run Configurations-android JUnit Test,更改你工程运行的Instrumentation runner,如果不更改,默认是android.test.InstrumentationTestRunner
Android Robotium黑盒测试封装为Apk_第6张图片

c、添加Activity
新建一个Activity作为程序入口,添加一个按钮开始测试,一个textview显示日志
Android Robotium黑盒测试封装为Apk_第7张图片

修改AndroidManifest.xml:
Android Robotium黑盒测试封装为Apk_第8张图片

Button点击事件执行脚本:
Android Robotium黑盒测试封装为Apk_第9张图片

五、测试
点击按钮——>运行脚本——–>打印Log
Android Robotium黑盒测试封装为Apk_第10张图片
Android Robotium黑盒测试封装为Apk_第11张图片

六、参考
Thanks:
http://blog.csdn.net/airyzhou/article/details/38268159
http://blog.sina.com.cn/s/blog_6abda9bc01015zoc.html
http://www.cnblogs.com/keke-xiaoxiami/p/4286744.html
http://blog.sina.com.cn/s/blog_5b478f870102v9my.html

Demo下载链接

你可能感兴趣的:(Android,测试)