热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android用单元测试的多,使用Robolectric做Android单元测试

首先谈谈,为什么要进行单元测试呢?理论上说,多了单元测试这一环节意味着要付出额外时间,如果开发周期不变,那么编

首先谈谈,为什么要进行单元测试呢?理论上说,多了单元测试这一环节意味着要付出额外时间,如果开发周期不变,那么编写代码的时间必须相应缩短。这岂不是作为程序猿的我们自己给自己找麻烦,吃力不讨好吗?讲真的,我一开始也有这种想法,怀着半信半疑的态度来做单元测试。后来慢慢地发现,单元测试过程帮助自己找出考虑不周或者意料之外的bug,即时修复。这样一来,去到测试人员手中的app瞬间变得高大上,bug出现率有所降低,减少了二次测试验证所浪费的时间。那么,做单元测试的必要性还是存在的,它可以帮助我们快速定位bug,从而修复bug,提高代码质量。曾经有一次,我无意间看到Jake Wharton这位Android界大神都做单元测试,而且是几乎每个类都进行细节测试。我们有什么理由不进行单元测试呢?目前有AndroidJUnit4、Dagger、Robolectric、Mockito这四个测试框架,现在选择Robolectric来介绍下。

1、在Android Studio的Gradle环境测试

Robolectric相关依赖:

testCompile 'org.robolectric:robolectric:3.0'

testCompile 'org.robolectric:robolectric-annotations:3.0'

testCompile 'org.robolectric:shadows-multidex:3.0'

testCompile 'org.robolectric:shadows-support-v4:3.0'

另外是测试常用的Juint依赖,现在是出到4.12版本:

testCompile 'junit:junit:4.12'

2、在Maven环境中测试

需要在pom.xml文件中添加以下依赖:

org.robolectric

robolectric

3.1.4

test

3、在Eclipse环境测试

需要安装m2e-android插件,点击project -> Run as -> JUnit Test, 然后选择Eclipse JUnit,就可以运行起来。

4、Linux和Mac平台注意要点

打开Edit Configuration,选择Defaults->JUint,修改Working directory为自己指定的工作目录,如下图:

0818b9ca8b590ca3270a3433284dd417.png

开始工作,需要在src目录下创建test文件夹,与main同级,如下图所示:

0818b9ca8b590ca3270a3433284dd417.png

接下来看下Robolectric基本测试类:

@RunWith(RobolectricGradleTestRunner.class)

@Config(cOnstants= BuildConfig.class)

public class SampleTest {

@Before

public void setUp(){

}

@Test

public void testSomeThing(){

}

@After

public void tearDown(){

}

}

其中,@RunWith指定在RobolectricGradleTestRunner类运行,@Config指定BuildConfig类作为constants常数,@Before方法里执行初始化操作,@Test执行真正测试,@After则是测试完毕的后续工作。@Before和@After不是非必须的。但是,如果没有添加@Config指定BuildConfig类作为constants常数,会抛出如下错误提示:

0818b9ca8b590ca3270a3433284dd417.png

值得注意的是,目前Robolectric只支持API21以下版本。如果你在gradle配置targetSdkVersion大于21,会抛出如下错误:

0818b9ca8b590ca3270a3433284dd417.png

初始化setUp方法里,可以是获取application实例,启动activity,根据id绑定控件等操作。

//获得application实例

application = ShadowApplication.getInstance();

//启动activity

activity = Robolectric.setupActivity(ToastActivity.class);

//断言application与activity不为null

assertNotNull(application);

assertNotNull(activity);

//通过activity找到对应id的控件

btn_toast = (Button) activity.findViewById(R.id.btn_toast);

et_username = (EditText) activity.findViewById(R.id.et_username);

这里的ShadowApplication是shadow for android.os.application,也就是说真实对象是application。而Robolectric.setupActivity方法其实是通过反射得到真正类,并完成初始化操作:

public static T setupActivity(Class activityClass) {

return ActivityController.of(shadowsAdapter, activityClass).setup().get();

}

在setup方法里,完成了onCreate、onStart、onResume等activity生命周期的调用。

public ActivityController setup() {

return create().start().postCreate(null).resume().visible();

}

下面模拟登陆成功的测试, 其中指定正确userName为hello,使用assertThat进行断言下一个activity为非null。

@Test

public void success(){

et_username.setText("hello");

btn_toast.performClick();

assertThat("The Next Activity Should Start", application.getNextStartedActivity(), is(notNullValue()));

Log.e("123456", "Hello, Robolectric!");

}

测试是pass了,但是并没有log打印出来。为什么呢?难道是Robolectric偷工减料,跳过log打印的步骤了?不是这样的,真正原因是Robolectric跑单元测试是在jvm环境运行,而log来自android.util。其实Robolectric也考虑到这边,只需要添加一行代码便可实现转换,让你的log正常输出。

//打印log日志

ShadowLog.stream = System.out;

果然,Robolectric并没有欺骗我们感情,期待的log终于出现了。

0818b9ca8b590ca3270a3433284dd417.png

好了,Robolectric做单元测试的基本用法已经介绍完毕。希望本文可以帮助大家开启单元测试之旅,尽情享受find bug & fix bug的乐趣。如果有什么问题,可以相互交流,为尽可能扼杀bug于摇篮,防bug于未然,提高代码质量,争取做一名更加出色的码农而奋斗。



推荐阅读
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
  • #前言AndroidArchitectureComponents是谷歌在GoogleIO2017发布的。官方的描述:https:developer.android.google.c ... [详细]
author-avatar
众神痴梦_325
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有