其他测试框架 Robolectric 环境搭建 ( Android Studio + Gradle )

xuxu · 2015年05月23日 · 最后由 付雷 回复于 2017年02月08日 · 2772 次阅读
本帖已被设为精华帖!

Robolectric-官网

Robolectric 官网文档少得可怜,可以选择 Eclipse + Maven , 也可以选择 Android Studio + Gradle
参考了 roboletric-samples ,踩了很多的坑。。

OK,接下来记录下我在 Mac 上的搭建步骤。其他系统可以参考。

各种软件版本:
JDK:1.8
Android Studio:1.2
Roboletric:3.0-SNAPSHOT

Robolectric 简介

其实很早就知道这个框架,但一直忍着没去碰它,而是选择先去熟悉了下 Instrumentation,这两天才忍不住......

InstrumentationRoboletric 都是针对 Android 进行单元测试的框架,前者在执行 case 时候是以 Android JUnit 的方式运行,因此必须在真实的 Android 环境中运行(模拟器或者真机),而后者则是以 Java Junit 的方式运行,这里就脱离了对 Android 环境的依赖,而可以直接将 case 在 JVM 中运行,大赞~,因此很适合将 Roboletric 用于 Android 的测试驱动开发。

网上其实还是比较多关于 Roboletric 的文章的,但是。。尼玛,里面都是贴点官网的示例代码,对于整个环境的搭建,却没多少提及的。。环境是最主要的,环境 OK 了,示例代码我到官网复制就 OK。。

新建 Android Project

新建 一个 Android 项目 ( RoboletricDemo ),一路默认,这里就不帖 MainActivity 的代码,代码很简单,该示例的主界面是一个 TextView,显示的内容为 Hello world!,界面中还有一个 Button,点击 Button,TextView 的内容会变为Hello xuxu!,呵呵。。

具体也可以参考这篇文章的内容:Android Instrumentation 简介
其中我对 sdk 的配置了 min sdk 为 16

配置 Gradle

  • 配置 RoboletricDemo/build.gradle

    ext {
        robolectricVersion = "3.0-SNAPSHOT"
    }
    
    subprojects {
        buildscript {
            repositories {
                jcenter()
            }
    
            dependencies {
                classpath "com.android.tools.build:gradle:1.2.2"
            }
        }
    
        repositories {
            maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
            mavenLocal()
            mavenCentral()
        }
    }
    
  • 配置 app/build.gradle

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 22
        buildToolsVersion "22.0.1"
    
        defaultConfig {
            applicationId "com.xuxu.roboletricdemo"
            minSdkVersion 16
            targetSdkVersion 19
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:22.0.0'
        testCompile "junit:junit:4.10"
        testCompile "org.assertj:assertj-core:1.7.0"
        testCompile "org.robolectric:robolectric:${robolectricVersion}"
    }
    
  • 配置 Build Variants

    在 Build Variants 面板中选择 Unit Tests

  • 完成添加依赖

    打开 Gradle 面板,点击刷新按钮

    完成之后可以在看到成功添加的所有依赖

完成 Test Case

  1. 重命名 app/src/androidTest 为 test,并且删除创建项目时自动生成的 ApplicationTest
  2. 在 MainActivity 中快速创建测试类,选择 JUnit 4,会自动创建 MainActivityTest 至之前修改的 test 目录下

  3. 编写 Test Case,这里直接贴上测试代码,代码都相当简单

    package com.xuxu.roboletricdemo;
    
    import android.widget.Button;
    import android.widget.TextView;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.robolectric.Robolectric;
    import org.robolectric.RobolectricGradleTestRunner;
    import org.robolectric.annotation.Config;
    
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertNotNull;
    import static org.junit.Assert.fail;
    
    /**
     * Created by xuxu on 15/5/23.
     */
    @RunWith(RobolectricGradleTestRunner.class)
    @Config(constants = BuildConfig.class)
    public class MainActivityTest {
    
        // 引用待测Activity
        private MainActivity mActivity;
    
        // 引用待测Activity中的TextView和Button
        private TextView textView;
        private Button button;
    
        @Before
        public void setUp() throws Exception {
            // 获取待测Activity
            mActivity = Robolectric.setupActivity(MainActivity.class);
    
            // 初始化textView和button
            textView = (TextView) mActivity.findViewById(R.id.textView);
            button = (Button) mActivity.findViewById(R.id.button);
        }
    
        // 测试界面初始化结果
        @Test
        public void testInit() throws Exception {
            assertNotNull(mActivity);
            assertNotNull(textView);
            assertNotNull(button);
    
            // 判断包名
            assertEquals("com.xuxu.roboletricdemo", mActivity.getPackageName());
    
            // 判断textView默认显示的内容
            assertEquals("Hello world!", textView.getText().toString());
        }
    
        // 测试点击button,textView显示的内容
        @Test
        public void testButton() throws Exception {
            // 点击button
            button.performClick();
    
            // 判断点击后textView的内容
            assertEquals("Hello xuxu!", textView.getText().toString());
        }
    
        // 一个失败的用例
        @Test
        public void testFail() throws Exception {
            fail("This case failed!");
        }
    }
    

    Run Test Case

  4. 运行方式

    1. 打开 Gradle 面板,在面板中执行测试

    2. 右键 MainActivityTest > Run 'MainActivityTest'

    3. 在终端中运行 ./gradlew test

  5. 查看报告

    执行完测试之后,会在 app/build/reports/tests/目录下生成相应地测试报告,使用浏览器打开

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 13 条回复 时间 点赞

发现帖子不支持 参考式 链接。。 这个是啥意思?

xuxu #12 · 2015年05月24日 Author

@lihuazhang Sorry, 是因为空格的原因。平常用 Markdown 写文档含多个链接的时候我通常是这样写的:

[Robolectric-官网][url-1]
[!image][image-1]

在末尾再加 [url-1]: http://robolectric.org

#2 楼 @xuxu 参考式链接不是应该这么用的吗?

[Robolectric-官网]
...

末尾加上:
[Robolectric-官网]: http://robolectric.org/

经试验,这么写是可以的:

Robolectric-官网
...

xuxu #10 · 2015年05月24日 Author

@chenhengjie123 嗯,都可以。

我这边查看报告三个 case 均 fail:fail 原因 java.lang.UnsupportedOperationException: Robolectric does not support API level 22;想问一下是不是应该还要配置一下 AndroidManifest.xml 这个文件

Error:Gradle DSL method not found: 'testCompile()' 提示找不到 testCompile() 方法,不知道有谁遇到过

EXTERNAL LIBRARIES 里面看到有对应的库,但是一直报各种包不存在,相当的郁闷。。。

为嘛我用 robolectric 去执行测试用例的时候老是报 classNotFound 呢,去 maven 库中下载好了解决了一个依赖再执行的时候又报另外个 classNotFound,一直就这样,简直就是无底洞,有哪位朋友碰到类似问题了吗?

各种图挂了

xuxu #4 · 2016年06月19日 Author

@snowdream 图床挂了。。还好本地还存了图片

@xyva 是的,我也一样遇到这个问题,,各种 classNotFound,超级多,,请问你后来解决了么?

xuxu #2 · 2016年06月27日 Author

@yzx200712256 应该是 gradle 中的依赖配置不全导致的。

@RunWith(RobolectricGradleTestRunner.class)

这个类已经在新版本去掉 ‘要使用 ’

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class SandwichTest {
}

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册