Robolectric 单元测试笔记

2016年4月11日

[TOC]

1、环境搭建(版本3.0)

Android单元测试需要JUnit框架的支持,Robolectric只是提供了Android代码的运行环境,测试还是需要junit来实现。配置如下:

testCompile 'junit:junit:4.10'
testCompile 'org.robolectric:robolectric:3.0'

然后在Build Variants中的Test Artifact改为Unit Tests

a-1-1.png-9.4kB
a-1-1.png-9.4kB

在Android Studio2.0正式版中没有这个选项,直至忽略掉。

2、第一次尝试

在Android studio下面有Test包,新建测试类TestDemoTest.

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class,
        sdk = 21,
        manifest = "src/main/AndroidManifest.xml",
        packageName = "cn.liucl.andoridunittestdemo",
        resourceDir = "res")
public class TestDemoTest {


    public static final String TAG = TestDemoTest.class.getSimpleName();
    private MainActivity mainActivity;

    @Before
    public void beforeTest() throws Exception {
        System.out.println("before");
    }

    @Test
    public void Testing() throws Exception {
        System.out.println("Testing()");
    }

}

第1行代码,使用注解的方式引入robolectric。然后看这个类的两个方法,使用before注解的方法,表示在单元测试之前执行,可用于获取Activity或资源文件等;而Test注解的方法表示就是这个测试case。执行之后,你会发现Robolectric cant found resource and AndroidManifest.xml这个错误。这是robolectric没有正确加载manifest文件。其实,Resources也没有被加载。这样就有这个类的第二个注解,也就是Config。在Config里面可以指定SDK版本,资源文件以及清单文件等信息。具体信息可以看他的注解。

补充:如果还是找不到资源,尝试把AndroidManifest中Application的Theme改成android:theme="@style/Theme.AppCompat"

注意,第一次运行需要下载sdk需要的组件,可能需要一段时间。如果下载失败,自备梯子。
a-1-2.png-63.2kB
a-1-2.png-63.2kB

图为正在下载。

3、带上Activity

Robolectric可以创建Activity,可以测试执行点击事件,可以测试生命周期等。

1、创建一个Activity
Robolectric提供对Activity的操作方法,我们获取一个Activity只需要Robolectric.setupActivity(MainActivity.class);就可以了。

@Before
public void beforeTest() throws Exception {
    System.out.println("before");
    mainActivity = Robolectric.setupActivity(MainActivity.class);
}

@Test
public void Testing() throws Exception {
    Assert.assertNotNull(mainActivity); //断言是否不为空
    System.out.println("Testing()");
}

下面是Robolectric的方法:


a-1-3.png-50.4kB
a-1-3.png-50.4kB

上面的buildActivity和setupActivity都可以创建Activity,他们的不同之处在于,setupActivity直接到Activity生命周期的运行阶段,而buildActivity只是获取对象

public static <T extends Activity> ActivityController<T> buildActivity(Class<T> activityClass) {
    return ActivityController.of(shadowsAdapter, activityClass);
}

public static <T extends Activity> T setupActivity(Class<T> activityClass) {
    return ActivityController.of(shadowsAdapter, activityClass).setup().get();
}
public ActivityController<T> setup() {
    return create().start().postCreate(null).resume().visible();
}

2、生命周期
ActivityController提供对Activity生命周期操作的一系列方法:(相同的,Service也是这样)

a-1-4.png-62.5kB
a-1-4.png-62.5kB

3、测试点击
Robolectric支持点击操作,首先确保Activity执行到相应的生命周期。在MainActivity编写好逻辑。

MainActivity

button = (Button) findViewById(R.id.test1);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("Success");
    }
});

TestDemoTest

@Before
public void beforeTest() throws Exception {
    Log.i(TAG, "beforeTest()");
    mainActivity = Robolectric.buildActivity(MainActivity.class).setup().get();//注意生命周期
    button = (Button) mainActivity.findViewById(R.id.test1);
}

@Test
public void btn1(){
    button.performClick();
}
在Robolectric中打Log请使用**System.out**。Android的Log工具只有在使用Adb时候才有效。

4、断言

Robolectric不提供类似Junit的assert方法来测试程序。所以还是需要使用Junit的assert来测试。

assertNotNull(); //判断对象是否不为空
assertNull();
assertEquals(); //判断实际值和期望值是否“相同”
assertTrue(); //判断布尔值是否为true
assertFalse();
assertNotSame();
assertSame(); //判断实际值和期望值是否为同一个对象

5、在项目中使用

实际项目中,单元测试对象与页面是一对一的,并不建议跨页面,这样的单元测试藕合度太大,维护困难。单元测试需要找到页面的入口,分析项目页面中的元素、业务逻辑,这里的逻辑不仅仅包括界面元素的展示以及控件组件的行为,还包括代码的处理逻辑。然后可以创建单元测试case列表(列表用于纪录项目中单元测试的范围,便于单元测试的管理以及新人了解业务流程),列表中记录单元测试对象的页面,对象中的case逻辑以及名称等。工程师可以根据这个列表开始写单元测试代码。
单元测试是工程师代码级别的质量保证工程,上述流程并不能完全覆盖重要的业务逻辑以及边界条件,因此,需要写完后,看覆盖率,找出单元测试中没有覆盖到的函数分支条件等,然后继续补充单元测试case列表,并在单元测试工程代码中补上case。
直到规划的页面中所有逻辑的重要分支、边界条件都被覆盖,该项目的单元测试结束。


a-1-5.jpg-169.5kB
a-1-5.jpg-169.5kB

参考

  1. http://tech.meituan.com/Android_unit_test.html
  2. http://stackoverflow.com/questions/18715983/robolectric-cant-found-resource-and-androidmanifest-xml
  3. http://www.xuxu1988.com/2015/05/23/robolectric-01/?utm_source=tuicool
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容