【达内课程】Android自动化测试框架Robotium

2023-11-13

Github地址

相关jar包下载

Robotium中各个类的用途

用途 方法
By 查询条件类,类似于UIAutomator的By类。只是,Robotium的By只用于查询WebElement对象. 例如,根据id获取web元素,或根据name获取web元素 8
Illustration 用于在屏幕上画点到点的路径 2
Illustration.Builder Illustration的工厂类 3
RobotiumUtils 用于对查找到的View列表,进行进一步的过滤和排序。 8
Solo Robotium的核心类,用于查找,滚屏,点击,等待等具体操作 216
Solo.Config Solo的内容类,用于Solo的默认设置。例如截图文件类型,log tag等,共12个成员变量 0
SystemUtils 用于控制WIFI和移动数据接口的开关 2
Timeout 用于设置/获取Timeout 4
WebElement 借由By对象查询到的WebView中的控件对象 17
Condition 接口 1
ScreenshotFileType 支持两种文件类型,JPEN和PNG 0

除Solo外,其他都是辅助类

Solo中除了构造函数外,共包含216个方法,分类看

在这里插入图片描述

小试牛刀

Robotium在Getting-Started中提供了简单示例。下载AS对应的项目,app/src/androidTest/java/com.example.android.notepad/NotePadTest.java,右键Run即可

测试1

我们在下载下来的项目基础上写一个关于登录的测试

首先新建MainActivity

public class MainActivity extends Activity {
    private EditText etName;
    private EditText etPassword;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etName = (EditText) findViewById(R.id.et_name);
        etPassword = (EditText) findViewById(R.id.et_pwd);
        button = (Button) findViewById(R.id.btn_login);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name = etName.getText().toString();
                String password = etPassword.getText().toString();
                if(name.equals("Errol_King") && password.equals("123456")){
                    Toast.makeText(MainActivity.this,"登录成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this,"登录失败", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

布局activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入姓名" />

    <EditText
        android:id="@+id/et_pwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码" />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"/>

</LinearLayout>

修改AndroidManifest中的启动页为MainActivity

       <activity android:name=".MainActivity" android:label="@string/title_notes_list">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        </activity>

当输入用户名Errol_King和密码123456后提示“登录成功”。当输入其他提示“登录失败”

现在来写测试代码,让程序自动输入用户名Errol_King和密码1234567,因为密码错误,所以会提示“登录失败”,如果页面上如期出现“登录失败”则测试通过

在以下目录下新建LoginTest文件
在这里插入图片描述

@RunWith(AndroidJUnit4.class)
public class LoginTest {

    @Rule
    public ActivityTestRule<MainActivity> activityTestRule =
            new ActivityTestRule<>(MainActivity.class);

    private Solo solo;

    //在执行我们的测试方法之前调用
    @Before
    public void setUp() throws Exception {
        //setUp() is run before a test case is started.
        //This is where the solo object is created.
        solo = new Solo(InstrumentationRegistry.getInstrumentation(),
                activityTestRule.getActivity());
    }

    //我们写的测试方法
    @Test
    public void testLogin(){
        solo.waitForText("登录");

        EditText name = (EditText) solo.getView(R.id.et_name);
        EditText pwd = (EditText) solo.getView(R.id.et_pwd);
        Button button = (Button) solo.getView(R.id.btn_login);

        //在用户名和密码输入框输入文字
        solo.enterText(name, "Errol_King");
        solo.enterText(pwd, "1234567");
        //点击登录按钮
        solo.clickOnView(button);

        boolean isSuccess = solo.searchText("登录失败");
        //boolean isSuccess = solo.searchText("Errol_King");
        //第一个参数:验证失败情况下,要显示的提示字符
        //第二个参数:要用来断言的表达式
        assertTrue("错误提示没有出现",isSuccess);
    }

    //我们写的测试方法执行完之后
    @After
    public void tearDown() throws Exception {
        //关闭打开的activity
        solo.finishOpenedActivities();
    }
}

右键,run
在这里插入图片描述
程序会在手机上自动运行
在这里插入图片描述
运行结束后,AS会提示测试通过
在这里插入图片描述
如果我们修改LoginTest中代码

boolean isSuccess = solo.searchText("用户名或密码错误");

因为页面上提示的是“登录失败”而非“用户名或密码错误”,所以测试会失败,AS也会提示失败原因
在这里插入图片描述

测试2

修改MainActivity中程序,登录成功后跳转UserActivity

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name = etName.getText().toString();
                String password = etPassword.getText().toString();
                if(name.equals("") && password.equals("")){
                    Toast.makeText(MainActivity.this,"用户名和密码不能为空", Toast.LENGTH_SHORT).show();
                }else{
                    if(name.equals("Errol_King") && password.equals("123456")){
                        Toast.makeText(MainActivity.this,"登录成功", Toast.LENGTH_SHORT).show();
                        startActivity(new Intent(MainActivity.this,UserActivity.class));
                    }else {
                        Toast.makeText(MainActivity.this,"登录失败", Toast.LENGTH_SHORT).show();
                    }
                }

            }
        });

其中UserActivity中有一个添加按钮

新建LoginTest2,其余代码不变,修改testLogin()方法

@Test
    public void testLogin(){
        solo.waitForText("登录");

        EditText name = (EditText) solo.getView(R.id.et_name);
        EditText pwd = (EditText) solo.getView(R.id.et_pwd);
        Button button = (Button) solo.getView(R.id.btn_login);

        //在用户名和密码输入框输入文字
        solo.enterText(name, "Errol_King");
        solo.enterText(pwd, "123456");
        //点击登录按钮
        solo.clickOnView(button);

        //判断有没有显示UserActivity
        solo.assertCurrentActivity("程序没有跳转",UserActivity.class);
        //判断页面上有没有显示添加按钮
        View view = solo.getView(R.id.btn_add);
        boolean isSuccess = view.isShown();
        assertTrue("没显示添加按钮",isSuccess);
    }

在这里插入图片描述
AS显示测试通过
在这里插入图片描述

测试3

我们修改UserActivity的代码,点击添加按钮,显示一个EditText和一个保存Button,单击保存按钮,如果输入内容为空,则提示“消息不能为空“,否则提示”留言成功“,并且动态添加View

public class UserActivity extends Activity {
    private Button btn_add;
    private Button btn_save;
    private EditText et_message;
    private View ll_container;
    private LinearLayout ll_list;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user);

        btn_add = (Button) findViewById(R.id.btn_add);
        btn_save = (Button) findViewById(R.id.btn_save);
        et_message = (EditText) findViewById(R.id.et_message);
        ll_container = findViewById(R.id.ll_container);
        ll_list = (LinearLayout)findViewById(R.id.ll_list);

        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ll_container.setVisibility(View.VISIBLE);
            }
        });

        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = et_message.getText().toString();
                if(message.equals("")){
                    Toast.makeText(UserActivity.this,"消息不能为空",Toast.LENGTH_SHORT).show();
                }else {
                    et_message.setText("");
                    Toast.makeText(UserActivity.this,"留言成功",Toast.LENGTH_SHORT).show();
                    addView(message);
                }
            }
        });
    }

    public void addView(String str) {
        TextView child = new TextView(this);
        child.setTextSize(20);
        child.setTextColor(Color.parseColor("#ff0000"));

        child.setText(str);
        ll_list.addView(child);
    }

}

修改LoginTest2中测试方法

//我们写的测试方法
    @Test
    public void testLogin(){
        solo.waitForText("登录");

        EditText name = (EditText) solo.getView(R.id.et_name);
        EditText pwd = (EditText) solo.getView(R.id.et_pwd);
        Button button = (Button) solo.getView(R.id.btn_login);

        //在用户名和密码输入框输入文字
        solo.enterText(name, "Errol_King");
        solo.enterText(pwd, "123456");
        //点击登录按钮
        solo.clickOnView(button);

        //判断有没有显示UserActivity
        solo.assertCurrentActivity("程序没有跳转",UserActivity.class);
        //判断页面上有没有显示添加按钮
        View view = solo.getView(R.id.btn_add);
        boolean isSuccess = view.isShown();
        assertTrue("没显示添加按钮",isSuccess);

        //单击添加按钮
        solo.clickOnView(view);
        //屏幕上有没有出现“待办事项”
        isSuccess = solo.searchText("待办事项");
        assertTrue(isSuccess);
        //模拟用户单击保存按钮
        view = solo.getView(R.id.btn_save);
        solo.clickOnView(view);
        isSuccess = solo.searchText("消息不能为空");
        assertTrue(isSuccess);
    }

在这里插入图片描述
AS提示测试成功

测试4

新建LoginTest3,代码从LoginTest2中粘过来,只修改测试方法

    @Test
    public void testLogin(){
        solo.waitForText("登录");

        EditText name = (EditText) solo.getView(R.id.et_name);
        EditText pwd = (EditText) solo.getView(R.id.et_pwd);
        Button button = (Button) solo.getView(R.id.btn_login);

        //在用户名和密码输入框输入文字
        solo.enterText(name, "Errol_King");
        solo.enterText(pwd, "123456");
        //点击登录按钮
        solo.clickOnView(button);

        //判断有没有显示UserActivity
        solo.assertCurrentActivity("程序没有跳转",UserActivity.class);
        //判断页面上有没有显示添加按钮
        View view = solo.getView(R.id.btn_add);
        boolean isSuccess = view.isShown();
        assertTrue("没显示添加按钮",isSuccess);

        //单击添加按钮
        solo.clickOnView(view);
        //屏幕上有没有出现“待办事项”
        isSuccess = solo.searchText("待办事项");
        assertTrue(isSuccess);
        //模拟输入内容(寻找页面上第一个EditText)
        EditText editText = solo.getEditText(0);
        solo.enterText(editText,"hello");

        //模拟用户单击保存按钮(根据按钮上的文本查找)
        view = solo.getButton("保存");
        solo.clickOnView(view);

        solo.assertCurrentActivity("当前页面不是UserActivity",UserActivity.class);
        //判断才输入的内容在不在屏幕上
        //"hello"要查找的文本
        //1出现次数,只需出现一次
        //true是否向下滚动
        //true只考虑显示的,隐藏的不管
        isSuccess = solo.searchText("hello",1,true,true);
        assertTrue(isSuccess);
    }

在这里插入图片描述

测试5

我们在屏幕上增加一个关闭按钮,长按关闭按钮,关闭UserActivity
修改UserActivity

tv_finish.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                finish();
                return false;
            }
        });

修改LoginTest3中测试方法

    @Test
    public void testLogin(){
        ......

        //长按
        solo.clickLongOnText("关闭");
        //等2s后,判断是否MainActivity
        isSuccess = solo.waitForActivity(MainActivity.class,2000);

        solo.clearEditText(name);
        solo.clearEditText(pwd);
        assertTrue(isSuccess);
    }

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【达内课程】Android自动化测试框架Robotium 的相关文章

随机推荐

  • 安卓逆向入门指南:修改与重打包应用

    安卓逆向入门指南 修改与重打包应用 概述 介绍修改与重打包应用的目的和应用场景 强调合法性和道德准则 在逆向工程过程中需要遵守相关法律法规 理解应用结构与资源 APK文件结构 解释APK文件的基本结构 包括AndroidManifest x
  • Spring Boot2.x 整合lettuce redis 和 redisson

    前言 springboot2之前redis的连接池为jedis 2 0以后redis的连接池改为了lettuce lettuce能够支持redis4 需要java8及以上 lettuce是基于netty实现的与redis进行同步和异步的通信
  • 基于RFID技术的预制件管理系统的开发

    1 简介 随着计算机 通讯技术和消费电子产品 正如人们通常所知的3C数码产品 的到来 已经在人们生活的各个领域带来了改变 通过这些3C技术 在将来 信息的传播和获取将变得更加便利 电子化管理技术正在向移动管理概念转变 射频识别系统 RFID
  • 微信支付官方SDK PHP版本接入记录

    1 下载证书 下载商家支付证书 这里忽略步骤 下载的证书我们放在E wwwroot certs wx 目录下 一共有4个文件 apiclient cert p12 apiclient cert pem apiclient key pem 证
  • [linux-022]ubuntu20.04用virtualbox安装64位win10彻底解决“directory ezboot not found”问题

    1 这问题是由于win10的iso文件超过4g导致的 2 解决关键 需要一个小尺寸的能用winpe启动的iso镜像 这个镜像有磁盘分区工具和ghost 3 在virtualbox创建win10 64虚拟机 硬盘50g 4 给这个虚拟机挂上两
  • PHP 之session cookie

    cookie和session有什么用 常见的用法 比如在有些网站下载东西需要会员先登陆 http协议本身是无状态的 无法得知顾客是否已经登陆 怎么办呢 cookie和session就可以知道 再比如网上购物 用户身份认证 程序状态记录 购物
  • shell经典面试题根据文件创建用户名及密码(亲测)

    转载来源 shell经典面试题根据文件创建用户名及密码 https www jianshu com p eeb455eef7ca 01 前言 shell脚本已经学习了很长一段时间了 现在时不时来看一些经典的面试题 复习一些常用知识点 温故知
  • IDEA必备的10款插件

    目录 1 Vuesion Theme 2 lombok 3 File Expander 4 GitToolBox 5 Maven Helper 6 Translation 7 arthas idea 8 Free Mybatis plugi
  • 递归问题------汉诺塔

    递归问题实际上是入栈出栈的一个过程 但有时候也会比较难理解 虽然用起来是比较方便的 1 include
  • windows文件传到linux导致文件类型错误处理

    问题 hadoop hadoop001 hadoop 2 6 0 cdh5 7 0 sbin start dfs sh 18 11 27 16 24 25 WARN util NativeCodeLoader Unable to load
  • VC++----using namespace std问题

    写一个简单的代码 cpp view plain copy print
  • 大数据组件-Flume集群环境的启动与验证

    大数据学习记录篇 持续更新中 个人主页 beixi 本文章收录于专栏 点击传送 大数据学习 持续更新中 感谢各位前辈朋友们支持学习 上一篇文章写到了Flume集群环境的安装 这篇文章接着上篇文章延伸Flume集群环境的启动与验证 如果Flu
  • JS:三种常用的函数定义方式

    js中函数也是一个对象 我们可以通过调用构造函数即new Function 的方式来定义 但是在 JavaScript 中 很多时候要尽量避免使用 new 关键字 因此这种方式并不推荐 了解即可 通常使用以下三种定义方式 命名函数 即最基本
  • ARMV8体系结构简介:AArch64系统级体系结构之Self-hosted debug

    1 前言 2 关于self hosted debug Debugger调试器 是操作系统或系统软件的一部分 它会处理debug exception或修改debug system register debugger运行在EL0 提供了用户de
  • VS Code 搭建 C/C++ 编译环境(clang)

    下载安装步骤 1 下载 LLVM 安装 比如我的安装在 E 盘 2 下载 MinGW w64 解压 无需安装 3 解压 MinGW w64 后 将 mingw64 下的文件拷贝到 LLVM 下 文件夹存在重名 合并即可 无冲突 我的环境 1
  • SpringCache -- Redis --- 配置与缓存使用--配置过期时间

    写在前面 学redis 还是得搭配SpringCache来玩一玩 前置内容 win安装 redis基础 springboot使用redis 文章目录 导入依赖 配置cache 使用 Cacheable CachePut CacheEvict
  • imx6ull: 从内核、buildroot配置实现ffmpeg+nginx+rtmp+USB摄像头

    前言 根据正点原子的教程 在官方提供的出厂根文件系统下很容易就实现了 I MX6U 嵌入式 Linux C 应用编程指南 第三十四章的视频监控项目 但是想自己从内核 根文件系统自己配置来实现整个流程 以便于在其他平台下能够迁移 而且也算是熟
  • Visual Studio Code+phpstudy(WampServer、LNMP...)搭建PHP开发环境

    VS Code是微软近年推出的一款文本编辑器 相关下载 https code visualstudio com Download phpstudy是将Apache Nginx PHP MySQ等等整合在一块的一个软件 为搭建软件开发 运行环
  • Python数据可视化的例子——直方图(hist)和核密度曲线(kde)

    直方图一般用来观察数据的分布形态 横坐标代表数值的均匀分段 纵坐标代表每个段内的观测数量 频数 一般直方图都会与核密度图搭配使用 目的是更加清晰地掌握数据的分布特征 下面将详细介绍该类型图形的绘制 1 matplotlib模块 matplo
  • 【达内课程】Android自动化测试框架Robotium

    文章目录 Robotium中各个类的用途 小试牛刀 测试1 测试2 测试3 测试4 测试5 Github地址 相关jar包下载 Robotium中各个类的用途 类 用途 方法 By 查询条件类 类似于UIAutomator的By类 只是 R