Robotium简要学习

Robotium是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手势操作(点击、长按、滑动等)、查找和断言机制的API,能够对各种控件进行操作。Robotium结合Android官方提供的测试框架达到对应用程序进行自动化的测试。另外,Robotium 4.0版本已经支持对WebView的操作。Robotium 对Activity,Dialog,Toast,Menu 都是支持的。



更多的Robotium文档可查询Robotium中文网站或者Robotium英文网站

Android代码:

package com.testshipping;

import android.test.ActivityInstrumentationTestCase2;
import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.robotium.solo.Solo;
//import android.widget.RelativeLayout;

@SuppressWarnings("rawtypes")
public class TestShipping extends ActivityInstrumentationTestCase2 {

    private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.ziipin.ship.ui.LauncherActivity";
    private static final String Tag = "ShippingLog";

    private static Class launcherActivityClass;
    private static String phone_no = "";
    private static String phone_sc = "";
    private static final int ticket_pay_way = 3; //默认使用现金账户支付,2为支付宝快捷支付,3为微信支付
    private static int now_day;
    private boolean is_login = true;

//
//    public TestShipping(Class activityClass) {
//        super(activityClass);
//        // TODO Auto-generated constructor stub
//    }

    static{
        try{
            launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
        }catch(ClassNotFoundException e){
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public TestShipping() throws ClassNotFoundException{
        super(launcherActivityClass);
    }

    private Solo solo;

    @Override
    protected void setUp() throws Exception{
        solo = new Solo(getInstrumentation(),getActivity());
//        getUserInfo();
        Log.v(Tag,"get activity。。。");
    }

    @Override
    public void tearDown() throws Exception{
        try{
            solo.finalize();
        }catch (Throwable e){
            e.printStackTrace();
        }
        solo.finishOpenedActivities();
        super.tearDown();
    }

    public void testLogin() throws Exception{
        Log.v(Tag, "testLogin is starting");
//        final String CurrentActivity;

        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 5000);

        //点击进入买船票的页面
        View textView = solo.getCurrentActivity().findViewById(4);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
        solo.clickOnView(textView);

        if (solo.searchText("忘记密码")){
            Log.v(Tag,"未登录,进入登录界面");
            Log.v(Tag,"starting ooooo");
            solo.clearEditText(0);
            solo.enterText(0, phone_no);
            solo.clearEditText(1);
            solo.enterText(1, phone_sc);
            solo.clickOnButton("登录");
        }

        if (solo.searchText("充值")){
            Log.v(Tag, "已登录,登录成功...");
            Log.v(Tag, "get_user_info is success.");
            //TODO 截图操作
            solo.clickOnText("消费明细");
            solo.scrollDown();
            solo.goBack();
        }

        solo.clickOnText("退出登录");
        solo.waitForDialogToOpen(1000);
        solo.clickOnButton("确认");
    }

    public boolean IsLogout(){
        try{
            solo.clickOnText("退出登录");
            solo.waitForDialogToOpen(1000);
            solo.clickOnButton("确认");
            return true;
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public void testLogout() throws Exception{
        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 5000);
        View textView = solo.getCurrentActivity().findViewById(4);
        solo.clickOnView(textView);

        if(solo.searchText("充值")){
            if(IsLogout()){
                solo.sleep(1000);
                if(solo.searchText("忘记密码")){
                    Log.v(Tag,"登出成功");
                }else{
                    Log.v(Tag,"登出失败");
                }
            }else{
                Log.v(Tag,"登出失败");
            }
        }

        if(solo.searchText("忘记密码")){

        }
    }

    public void testMyOrderAndPay() throws Exception{
        Log.v(Tag,"我的订单");
        String clickorder = "本地订单";
        is_login = IsLogin();
        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 1000);

        //点击进入买船票的页面
        View textView = solo.getCurrentActivity().findViewById(5);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
        solo.clickOnView(textView);        

        if(is_login){
            //TODO
            clickorder = "我的订单";
        }else{
            //TODO
            clickorder = "本地订单";
        }

        solo.clickOnButton(clickorder);
        solo.clickOnButton("查询订单");
        solo.clickOnButton(clickorder);

        solo.clickOnButton(3);//本地订单,查询订单,船票订单;分别对应button index未1,2,3

        if(solo.searchText("未使用")){
            solo.clickOnText("未使用");
            solo.sleep(1000);

            if(solo.searchText("订单一")){
                if(solo.searchButton("立即付款")){
                    solo.clickOnButton("立即付款");
                    SelectPayWay(is_login);
                }
//
//                if(solo.searchText("发送朋友")){
//                    solo.clickOnText("发送朋友",1);
//                    solo.waitForDialogToOpen();
//                    solo.enterText(0, phone_no);
//                    solo.clickOnButton("发送");
//                }

            }
//            solo.clickOnText("历史");
//            solo.sleep(1000);
//            solo.goBack();

        }
//        solo.sleep(1000);
//        solo.clickOnText("查询订单");
//        solo.enterText(0, phone_no);
////        solo.clickOnButton("获取验证码");
//        solo.goBack();
    }

    @SuppressWarnings("unused")
    public void testMyOrderAndCancelPay() throws Exception{
        Log.v(Tag,"我的订单");
        final String clickorder ;
        is_login = IsLogin();
        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 1000);

        //点击进入买船票的页面
        View textView = solo.getCurrentActivity().findViewById(5);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
        solo.clickOnView(textView);        

        if(is_login){
            //TODO
            clickorder = "我的订单";
        }else{
            //TODO
            clickorder = "本地订单";
        }
        solo.clickOnButton(3);
        if(solo.searchText("订单一")){
            if(solo.searchButton("取消订单")){
                solo.clickOnButton("取消订单");
                solo.waitForDialogToOpen(1000);
                solo.clickOnButton("放弃取消");
            }
            solo.waitForDialogToClose(1000);

            if(solo.searchButton("取消订单")){
                solo.clickOnButton("取消订单");
                solo.waitForDialogToOpen(1000);
                solo.clickOnButton("确认取消");
            }
        }
    }

    public void testOrderSingleTicket() throws Exception{
        Log.v(Tag,"买单程船票");
        Log.v(Tag,"testOrderSingleTicket。。。。");
        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 5000);
        is_login=IsLogin();

        //点击进入买船票的页面
        View BuyTicket = solo.getCurrentActivity().findViewById(3);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
        solo.clickOnView(BuyTicket);

        solo.clickOnRadioButton(0);//页面使用RadioButton(单程)为0,往返为1

        //选择出发地点
        Log.v(Tag, "选择出发地点");
        solo.clickOnText("出发地点");
        solo.clickOnText("广州-番禺莲花山");
        solo.sleep(1000);

        //选择到达地点
        Log.v(Tag, "选择到达地点");
        solo.clickOnText("到达地点");
        solo.clickOnText("香港-中港码头");
        solo.sleep(1000);

        //选择出发日期
        Log.v(Tag, "选择出发日期");
        solo.clickOnText("出发日期");
        //获取需要点击的时间日
        int day = GetCurrentDay();
        if(day<=10){
            //day为index
            day = day + 30;
        }else{
            day = day + 39;
        }
        View time_day = null;
        time_day = solo.getView(TextView.class, day);
        solo.clickOnView(time_day);

        solo.clickOnButton("选择航班");

        //获取航班列表,固定选取当前能选取的最后的航班
//        ArrayList<TextView> list = solo.clickInList(0);
//        if (list.isEmpty()){
//            solo.clickOnText("前一天");
//        }
        solo.sleep(500);
        solo.clickInList(3, 0);

        solo.clickOnText("普通舱");
        solo.clickOnText("头等舱");

        solo.clickOnButton(3);
        solo.clickOnButton(5);
        solo.clickOnText("立即购票");

        if(solo.waitForDialogToOpen(1000)){
            Log.v(Tag,"成人票和儿童票不一致");
            if(solo.searchText("提示")){
                solo.clickOnButton("继续");
            }
        }

        SelectPayWay(is_login);
        Log.v(Tag,"完成买船票");
    }

    public void testOrderDoubleTicket() throws Exception{
        Log.v(Tag,"testOrderDoubleTicket starting...");

        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 5000);
        is_login=IsLogin();

        //点击进入买船票的页面
        View BuyTicket = solo.getCurrentActivity().findViewById(3);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
        solo.clickOnView(BuyTicket);

        solo.clickOnRadioButton(1);//页面使用RadioButton(单程)为0,往返为1

        solo.clickOnText("出发地点");
        solo.clickOnText("广州-番禺莲花山");
        solo.sleep(1000);

        solo.clickOnText("到达地点");
        solo.clickOnText("香港-中港码头");
        solo.sleep(1000);

        solo.clickOnText("出发日期");
        int day = GetCurrentDay();
        if(day<=10){
            //day为index
            day = day + 29;
        }else{
            day = day + 38;
        }

        View time_day = null;
        time_day = solo.getView(TextView.class, day);
        solo.clickOnView(time_day);

        solo.clickOnText("出发航班");
        solo.sleep(1000);
        solo.clickInList(3, 0);

        //返程日期使用默认输入的日期
        solo.clickOnText("返程航班");
        solo.clickInList(3, 0);
        solo.clickOnButton("下订单");
//        solo.clickOnButton(5);
        solo.clickOnButton("立即购票");
        SelectPayWay(is_login);
        Log.v(Tag,"购票完成");
    }

    //该方法需要在一个test最初进行调用
    private boolean IsLogin(){
        Log.v(Tag,"IsLogin。。。");
        solo.waitForActivity(LAUNCHER_ACTIVITY_FULL_CLASSNAME, 5000);

        //点击进入买船票的页面
        View BuyTicket = solo.getCurrentActivity().findViewById(4);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
        solo.clickOnView(BuyTicket);
        if(solo.searchText("个人账户")){
            solo.goBack();
            return true;
        }
        solo.goBack();
        return false;

    }

    @SuppressWarnings("unused")
    private void Logout(){

        if(IsLogin()){
            View BuyTicket = solo.getCurrentActivity().findViewById(4);//3、4、5分别代表主要当中的可点击的三个,按顺序进行
            solo.clickOnView(BuyTicket);
            solo.clickOnButton("退出登录");
        }
        solo.goBack();
    }

    //可能重复使用到的函数
    private int GetCurrentDay(){
        Time now_t = new Time();
        now_t.setToNow();
        now_day = now_t.monthDay;

        return now_day;
    }

    private void SelectPayWay(final boolean is_login){
        Log.v(Tag,"Select Pay way");

        if(solo.searchText("选择支付方式")){
            if(!is_login){
                Log.v(Tag,"未登录");
                if(solo.searchText("登录/注册")){
                    solo.clickOnText("登录/注册");
                    solo.sleep(1000);
                    if(solo.searchText("会员中心")){
                        //注册新用户
                        solo.clickOnButton("注册");
                        if(solo.searchText("请输入电话号码")){
                            solo.enterText(0, phone_no);
                            solo.sleep(5000);
                            if(solo.searchText("号码已存在,请重新输入")){
                                Log.v(Tag,"注册页面OK。。。");
                                solo.goBack();
                            }
                        }

                        //进入登录页面登录
                        solo.clearEditText(0);
                        solo.clearEditText(1);
                        solo.enterText(0, phone_no);
                        solo.enterText(1, phone_sc);
                        solo.clickOnButton("登录");
                    }
                }
            }else{
                Log.v(Tag,"已经登录");
                solo.clickOnText("充值");
                solo.goBack();
            }

            switch(ticket_pay_way){
            case 2:
                solo.clickOnText("支付宝快捷支付");
                break;
            case 3:
                solo.clickOnText("微信支付");
                break;
            default:
                solo.clickOnText("现金账户支付");
                break;
            }
        }

        solo.clickOnButton("立即支付");
        solo.sleep(5000);
        solo.goBack();
    }
}

通过以上代码可知,在编写测试类的时候,需要注意的是:

  • 测试类需要继承自ActivityInstrumentationTestCase2
  • 需要在测试包中导入robotium-solo-x.x.x.jar,以便能够在代码中import com.robotium.solo.Solo;
  • 测试类中需要有一个launcherActivityClass(启动activity),以便启动对应的测试APP,否则无法进行测试;

当然,如果要此测试类能够正常执行,还需要在androidmanifest.xml中配置。

<instrumentation
        android:name="android.test.InstrumentationTestRunner"
     android:targetPackage="com.your.packagename" />
时间: 2024-10-04 00:18:12

Robotium简要学习的相关文章

JavaScript权威设计--JavaScript函数(简要学习笔记十)

1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"likeZqz()".有些些函数是用作内部用的或者为私有函数通常以一条下划线为前缀,就像"_zqzName()". 2.以表达式方式定义的函数 如: var zqz=function (){ return "zhaoqize"; } 在使用的时候必须把它赋值给一个变

linux下的bash编程简要学习

linux下的bash编程简要学习     1.bash是什么: linux运行时系统只会运行系统运行所需要的运行脚本即系统守护进程,一般根据用户自己需求设定和实现的服务需要手动启动,这种服务进程通常由bash启动,脚本中的命令通常被按照一定规则被bash读取视作参数,因此在脚本头部要申明运行的bash类型,bash命令分为内建命令及外部命令,外部命令通过PATH进行依次查找. bash读取命令后将其启动(fork)成为一个进程,依次启动服务     2.bash控制语句:         本地

GFS简要学习

GFS是Google提出的分布式文件系统,它由一个单一的master服务器以及多个chunk文件服务器组成,master服务器主要对命名空间.文件和chunk的映射以及chunk所在服务器的位置进行管理(包括文件的锁管理),chunk服务器主要存储chunk文件,单个chunk文件最大为64M,以文件的形式保存. 下面问题来了,对于一个文件系统,主要关心的问题是文件如何写入和读取,对于一个分布式文件系统,我们还要关心系统的可靠性以及一致性,对于GFS的学习,本人也从回答上述问题入手. 1.文件读

Spark简要学习

什么是Spark? 在Apache的网站上,有非常简单的一句话,'Spark is a fast and general engine',就是说Spark是一个统一的计算引擎,而且突出fast.那么具体是做什么的?是做large-scale的processing,即大数据处理. Spark is a fast and general engine for large-scale processing. 这句话非常简单,但是它突出了Spark的一些特点:第一个特点就是Spark是一个并行式的.内存

JavaScript权威设计--Window对象之Iframe(简要学习笔记十四)

1.Window对象属性的文档元素(id) 如果在HTML文档中用id属性来为元素命名,并且如果Window对象没有此名字的属性,Window对象会赋予一个属性,它的名字是id属性的值,而他们的值指向表示文档元素的HTMLElement对象. Window对象是以全局对象的形式存在于作用域链的最上层,这就意味着HTML文档中使用的id属性会成为可以被脚本访问的全局变量. 如: <button id="but"/> 就可以通过全局变量but来引用此元素. 2.多窗体窗口(if

JavaScript权威设计--Window对象(简要学习笔记十三)

1.Window对象是所有客户端JavaScript特性和API的主要接入点. Window对象中的一个重要属性是document,它引用Document对象. JavaScript程序可以通过Document对象和它包含的Element对象遍历和管理文档. 2.URL中的JavaScript 在URL后面跟一个JavaScript:协议限定符.里面的代码会作为JavaScript代码进行运行,需用分号分割. 如: <a href="javascript:alert('OK!')"

JavaScript权威设计--JavaScript函数(简要学习笔记十一)

1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScript构造函数调用的语法是允许省略实参列表和圆括号的. 如: var o=new Object(); //->等价于 var o=new Object; 第四种:使用call()与apply()间接调用(放在后面详细说明) 2.函数的实参与形参——可选形参 先看一个例子: function getA(

JavaScript权威设计--JavaScript数组(简要学习笔记九)

1.数组的创建 如: var a=[1.1,null,"a"]; var b=[1, ,3]; //中间的那个元素是undefined var c=[ , , ] 这里c.length你是不是以为是3? 哈哈,长度应该是2.因为数组直接量的语法允许有可选的结尾逗号. 2.数组索引的其他种类 a[-1.23]=true    //创建一个名为-1.23的属性 a["1000"]=0    //如果是字符串,它就转换为数组的索引 a[1.000]    //和a[1]相

JavaScript权威设计--JavaScript表达式与运算符,语句(简要学习笔记六)

1.delete是一元操作符,用来删除对象属性或者元素. var a={ x:1, y:2 } delete a.x; //删除x属性 “x”in a //false:a对象中已经不存在x属性 alert(a.x) //undefined;这里还是存在“东西”的 就如: var b=[1,2,3]; delete b[0]; b.length //3:还是3,虽然上面已经删除了b[0] 2.void运算符 void忽略操作的值,因此在操作数具有辅助作用的时候使用void来让程序更具语义 例子: