Robotium自动化测试框架教程

Robotium自动化测试框架教程

【免费下载链接】robotium Android UI Testing 【免费下载链接】robotium 项目地址: https://gitcode.com/gh_mirrors/rob/robotium

概述

Robotium是一个强大的Android UI自动化测试框架,支持原生应用和混合应用的测试。它提供了简单易用的API,让开发者能够快速编写稳定可靠的自动化测试用例。Robotium基于Instrumentation框架构建,可以直接与Android测试类如ActivityInstrumentationTestCase2和SingleLaunchActivityTestCase配合使用。

核心优势

  • 全面支持:原生应用、混合应用、WebView
  • 简单易用:API设计直观,学习成本低
  • 自动处理:多Activity切换、对话框、菜单等
  • 稳定可靠:运行时绑定UI组件,测试用例更健壮
  • 高效执行:测试执行速度快,适合持续集成

环境配置

Maven依赖配置

<dependency>
    <groupId>com.jayway.android.robotium</groupId>
    <artifactId>robotium-solo</artifactId>
    <version>5.6.3</version>
    <scope>test</scope>
</dependency>

Gradle配置

dependencies {
    androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.6.3'
}

核心组件架构

mermaid

基础用法

初始化Robotium

public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {
    
    private Solo solo;
    
    public LoginActivityTest() {
        super(LoginActivity.class);
    }
    
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        solo = new Solo(getInstrumentation(), getActivity());
    }
    
    @Override
    protected void tearDown() throws Exception {
        solo.finishOpenedActivities();
        super.tearDown();
    }
}

常用操作示例

1. 点击操作
// 点击文本
solo.clickOnText("登录");
solo.clickOnText("确定", 1); // 点击第二个匹配的"确定"文本

// 点击按钮
solo.clickOnButton("提交");
solo.clickOnButton(0); // 点击第一个按钮

// 点击视图
View loginButton = solo.getView(R.id.btn_login);
solo.clickOnView(loginButton);

// 长按操作
solo.clickLongOnText("删除");
solo.clickLongOnView(deleteButton, 2000); // 长按2秒
2. 文本输入
// 在EditText中输入文本
solo.enterText(0, "test@example.com"); // 在第一个EditText中输入
solo.enterText(solo.getEditText(R.id.et_password), "password123");

// 清空文本
solo.clearEditText(0);
solo.clearEditText(solo.getEditText(R.id.et_username));

// 模拟键盘输入
solo.typeText(0, "slow typing"); // 逐个字符输入
3. 等待和断言
// 等待元素出现
solo.waitForText("欢迎页面", 1, 5000); // 等待5秒
solo.waitForView(R.id.welcome_layout);
solo.waitForView(TextView.class, 2, 3000); // 等待第二个TextView

// 断言当前Activity
solo.assertCurrentActivity("应该在主页面", MainActivity.class);
solo.assertCurrentActivity("应该是登录页面", "LoginActivity");

// 内存断言
solo.assertMemoryNotLow();
4. 滚动操作
// 滚动到列表底部/顶部
solo.scrollToBottom();
solo.scrollToTop();

// 滚动列表到指定行
solo.scrollListToLine(listView, 20); // 滚动到第20行

// 指定方向滚动
solo.scrollToSide(Solo.RIGHT); // 向右滚动
solo.scrollToSide(Solo.LEFT, 0.5f, 10); // 向左滚动50%,10步

高级功能

WebView测试

// 等待Web元素
solo.waitForWebElement(By.id("submit-btn"));
solo.waitForWebElement(By.name("username"), 3, 5000, true);

// 点击Web元素
solo.clickOnWebElement(By.cssSelector(".login-button"));
solo.clickOnWebElement(By.xpath("//button[@type='submit']"), 1, true);

// 在Web元素中输入文本
solo.enterTextInWebElement(By.id("email"), "user@example.com");
solo.typeTextInWebElement(By.name("password"), "secret123", 0);

RecyclerView操作

// 点击RecyclerView中的项目
solo.clickInRecyclerView(3, 0, R.id.item_layout); // 点击第一个RecyclerView的第4个项目

// 等待RecyclerView项目
boolean found = solo.waitForText("Item 5", 1, 3000);

手势操作

// 拖拽操作
solo.drag(100, 300, 200, 400, 10); // 从(100,200)拖拽到(300,400),10步

// 缩放手势
PointF start1 = new PointF(100, 200);
PointF start2 = new PointF(300, 200);
PointF end1 = new PointF(50, 200);
PointF end2 = new PointF(350, 200);
solo.pinchToZoom(start1, start2, end1, end2);

// 旋转手势
PointF center1 = new PointF(200, 300);
PointF center2 = new PointF(200, 400);
solo.rotateLarge(center1, center2);

截图功能

// 单张截图
solo.takeScreenshot(); // 默认名称
solo.takeScreenshot("login_screen"); // 指定名称
solo.takeScreenshot("high_quality", 90); // 指定质量(0-100)

// 连续截图序列
solo.startScreenshotSequence("animation", 80, 100, 50); // 质量80,间隔100ms,最多50帧
// ... 执行动画操作 ...
solo.stopScreenshotSequence();

配置选项

Config类配置

public void setUp() throws Exception {
    Solo.Config config = new Solo.Config();
    config.timeout_small = 15000; // 小超时15秒
    config.timeout_large = 30000; // 大超时30秒
    config.sleepDuration = 300;   // 睡眠时间300ms
    config.sleepMiniDuration = 150; // 最小睡眠时间150ms
    config.shouldScroll = true;   // 启用自动滚动
    config.useJavaScriptToClickWebElements = true; // 使用JS点击Web元素
    
    solo = new Solo(getInstrumentation(), config, getActivity());
}

超时配置

// 全局超时设置
Timeout.setSmallTimeout(8000);   // 设置小超时为8秒
Timeout.setLargeTimeout(20000);  // 设置大超时为20秒

// 方法级别超时
solo.waitForText("加载完成", 1, 10000); // 等待10秒
solo.waitForView(R.id.content, 1, 15000, true); // 等待15秒

最佳实践

测试用例组织结构

public class ComprehensiveAppTest extends ActivityInstrumentationTestCase2<MainActivity> {
    
    private Solo solo;
    
    public ComprehensiveAppTest() {
        super(MainActivity.class);
    }
    
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        solo = new Solo(getInstrumentation(), getActivity());
    }
    
    public void testLoginFlow() {
        // 测试登录流程
        solo.enterText(0, "testuser");
        solo.enterText(1, "password123");
        solo.clickOnButton("登录");
        solo.waitForActivity(DashboardActivity.class, 5000);
        solo.assertCurrentActivity("应该在仪表板", DashboardActivity.class);
    }
    
    public void testNavigation() {
        // 测试导航功能
        solo.clickOnText("设置");
        solo.waitForText("系统设置", 1, 3000);
        solo.goBack();
        solo.waitForActivity(MainActivity.class, 3000);
    }
    
    public void testDataValidation() {
        // 测试数据验证
        solo.enterText(0, "invalid-email");
        solo.clickOnButton("提交");
        assertTrue("应该显示错误消息", solo.waitForText("邮箱格式错误", 1, 2000));
    }
    
    @Override
    protected void tearDown() throws Exception {
        solo.finishOpenedActivities();
        super.tearDown();
    }
}

异常处理策略

public void testRobustScenario() {
    try {
        // 尝试执行可能失败的操作
        solo.clickOnText("不存在的按钮");
        fail("应该抛出异常");
    } catch (Exception e) {
        // 优雅地处理异常,继续测试
        Log.d("Test", "预期中的异常: " + e.getMessage());
    }
    
    // 使用waitFor方法处理异步操作
    if (solo.waitForText("加载中", 1, 3000)) {
        solo.waitForText("加载完成", 1, 10000);
    }
    
    // 检查网络状态
    if (!solo.waitForCondition(new Condition() {
        @Override
        public boolean isSatisfied() {
            return isNetworkAvailable();
        }
    }, 5000)) {
        Log.w("Test", "网络不可用,跳过网络相关测试");
        return;
    }
}

性能优化技巧

public void testPerformance() {
    // 调整等待策略
    Solo.Config config = new Solo.Config();
    config.sleepDuration = 100;  // 减少等待时间
    config.sleepMiniDuration = 50;
    solo = new Solo(getInstrumentation(), config, getActivity());
    
    // 批量操作减少UI交互
    solo.enterText(0, "user");
    solo.enterText(1, "pass");
    solo.clickOnButton("登录");
    
    // 使用更精确的选择器
    solo.clickOnView(solo.getView(R.id.specific_button));
    instead of
    solo.clickOnText("按钮");
}

常见问题解决方案

1. 元素找不到问题

// 解决方案:增加等待时间和滚动
solo.waitForText("目标文本", 1, 10000, true); // 等待10秒,启用滚动

// 使用更精确的定位方式
View specificView = solo.getView(R.id.unique_id, 0);
solo.clickOnView(specificView);

// 检查是否在正确的Activity
solo.assertCurrentActivity("应该在正确的页面", ExpectedActivity.class);

2. WebView测试问题

// 确保WebView已加载完成
solo.waitForWebElement(By.id("web_element"), 1, 15000, true);

// 使用JavaScript点击(如果需要)
Solo.Config config = new Solo.Config();
config.useJavaScriptToClickWebElements = true;
solo = new Solo(getInstrumentation(), config, getActivity());

3. 异步操作处理

// 使用waitForCondition处理复杂异步场景
solo.waitForCondition(new Condition() {
    @Override
    public boolean isSatisfied() {
        return solo.searchButton("下一步") && 
               !solo.searchText("加载中");
    }
}, 10000);

// 组合等待条件
solo.waitForText("操作完成", 1, 5000);
solo.waitForView(R.id.success_indicator);

调试技巧

日志调试

// 启用Robotium命令日志
Solo.Config config = new Solo.Config();
config.commandLogging = true;
config.commandLoggingTag = "RobotiumTest";
solo = new Solo(getInstrumentation(), config, getActivity());

// 查看当前视图层次
ArrayList<View> views = solo.getViews();
for (View view : views) {
    Log.d("ViewDebug", "View: " + view.getClass().getSimpleName() + 
          ", ID: " + (view.getId() == View.NO_ID ? "NO_ID" : view.getResources().getResourceName(view.getId())));
}

可视化调试

// 使用illustrate方法可视化操作
solo.illustrate(new Illustration.Builder()
    .addPoint(100, 200, 1.0f)
    .addPoint(300, 400, 0.5f)
    .build());

// 截图调试
solo.takeScreenshot("debug_step_1");
// 执行操作...
solo.takeScreenshot("debug_step_2");

集成到CI/CD流程

Jenkins配置示例

pipeline {
    agent any
    stages {
        stage('测试') {
            steps {
                sh './gradlew connectedAndroidTest'
            }
            post {
                always {
                    junit '**/build/test-results/**/*.xml'
                    archiveArtifacts '**/build/outputs/androidTest-results/**/*'
                }
            }
        }
    }
}

测试报告生成

<!-- 在build.gradle中配置测试报告 -->
android {
    testOptions {

【免费下载链接】robotium Android UI Testing 【免费下载链接】robotium 项目地址: https://gitcode.com/gh_mirrors/rob/robotium

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值