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" />

Robotium简要学习的更多相关文章

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

    1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...

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

    1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"lik ...

  3. ECMAScript 6.0 简要学习

    由于在学习vue的时候有许多自己不懂的语法,于是简单的学习一下ES6. 1.ES简介 ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ...

  4. Python简要学习笔记

    1.搭建学习环境 推荐ActivePython,虽然此乃为商业产品,却是一个有自由软件版权保证的完善的Python开发环境,关键是文档以及相关模块的预设都非常齐备. ActivePython下载地址: ...

  5. Robotium 框架学习之概述

    框架目的: Robotium is an Android test automation framework that has full support for native and hybrid a ...

  6. $tarjan$简要学习笔记

    $QwQ$因为$gql$的$tarjan$一直很差所以一直想着要写个学习笔记,,,咕了$inf$天之后终于还是写了嘻嘻. 首先说下几个重要数组的基本定义. $dfn$太简单了不说$QwQ$ 但是因为有 ...

  7. 高性能JavaScript--快速响应的用户界面(简要学习笔记三)

    1.浏览器线程:用于执行JavaScript和更新用户界面的进程被称为“浏览器UI线程”.   2. <1>定时器的出现让出UI线程控制权 setTimeout(),setInterval ...

  8. 高性能JavaScript--数据存储(简要学习笔记二)

    1.JavaScript中四种基本数据存取位置:字面量,本地变量,数组元素,对象成员. 一般来说:[字面量,局部变量]运行速度>[数组,对象成员]   2.内部属性包含了一个函数被创建的作用域中 ...

  9. JavaScript权威设计--jQuery,Ajax.animate,SVG(简要学习笔记二十)[完结篇]

    1.$和jquery在全局命名空间中定义的唯一两个变量.   2.jquery是工厂函数,不是构造函数.他返回一个新创建的对象.   3.jquery的四种调用方式:     <1>传递C ...

随机推荐

  1. 无法解析指定的连接标识符 oracle错误12154

    导出的时候老是报这个错,exp userid=c##yh/yh@MyOracle tables=(stu3) file=d:\e.dmp; 解决了好久,最后都失败了,后来加了127.0.0.1:152 ...

  2. 深入理解JVM—字节码执行引擎

    原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220122204355694/ 前面我们不止一次的提到,Java是一种跨平台的语言,为 ...

  3. mysql字段的适当冗余有利于提高查询速度

    CREATE TABLE `comment` (  `c_id` int(11) NOT NULL auto_increment COMMENT '评论ID',  `u_id` int(11) NOT ...

  4. iOS 开发--github的demo

    令人惊讶的是,YYText 虽然代码量很大(超过一万行),但它只是 ibireme 的作品之一.ibireme 利用业余时间完成了 YYKit 工具库,包括: YYModel — 高性能的 iOS J ...

  5. 开源调度框架Quartz最佳实践

    开源调度框架Quartz最佳实践 Quartz是一个Java调度框架,当前的最新版本为2.2.1. 以Quartz 2.2.1版为例,Quartz最佳实践(用于生产系统)总结如下: 1.跳过更新检查Q ...

  6. Java ssh 访问windows/Linux

     Java ssh 访问windows/Linux 工作中遇到的问题: Java code运行在一台机器上,需要远程到linux的机器同时执行多种命令.原来采用的方法是直接调用ssh命令或者调用pli ...

  7. 对原生态jdbc程序中问题总结

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  8. Android开发之获取系统管理权限,即DevicePolicyManager和DeviceAdminReceiver的使用

    参考:http://www.cnblogs.com/androidez/archive/2013/02/17/2915020.html 1.创建AdminReceiver,继承DeviceAdminR ...

  9. mac下app store 无法完成您的购物操作

    最近在mac下使用app store 的时候出现提示:“我们无法完成您的购物操作 网络连接已中断”.但是我的网络是好的,图片如下: 网上找了各种解决办法,比如将DNS改成 114.114.114.11 ...

  10. Deferred的那些知识

    在移动开发中的各种中,我们一定会遇到异步回调的问题,比如: 1:Css3执行动画完毕, 回调 2:Jquery Animate动画的执行完毕, 回调 3:Ajax的执行(并行.串行),回调 等等   ...