使用 robolectric 做单元测试
来源:互联网 发布:电脑能写小说的软件 编辑:程序博客网 时间:2024/05/21 18:37
简述
上文android 如何开始测试提到了测试的基本知识,我也是初次接触测试,可能存在误解,如果各位发现,还请不吝指正。
基本介绍
如果你对Robolectric不够了解,可以先阅读以下链接:
- Robolectric 官网指南
- Robolectric GitHub
- Robolectric 2.4 升级 3.0对比WIKI
- Robolectric GitBook
- 用Robolectric来做Android unit testing
- Robolectric Github 官方示例
- Robolectric Github 其他开发者提供的示例
- Robolectric Github 在开源项目
Android-Boilerplate
中运用
常见问题
- 异步任务
- 如何使用内置的shadow对象
- 准备测试环境
- 测试时,Application 对象获取为 null。(见下方项目实践)
- 测试时,需要有选择的在Application中初始化代码。见下方项目实践)
后续遇到其他问题,再进行补充
项目实践
遇到的第一个问题:如何有选择的在 Application 初始化?
通常一段 App
的初始化代码如下。
public class App extends Application{ // ignore some code @Override public void onCreate () { super.onCreate (); if (isMainProcess ()) { setupCrashReporting (); setupUmeng (); setupBasic (); setupComponent (); } } // ignore some code}
但是:
- 如果使用
setupUmeng
友盟的一系列服务,可能会导致测试过程中衍伸出一些不必要的错误警告。 - 若在
App
中实现了Thread.UncaughtExceptionHandler
接口,来完成错误收集功能。则会导致单元测试时,无法正常执行。 - 亦或者,需要在单元测试时初始化一些正常运行时额外的一些服务。
但是通常,直接更改App
会导致代码中的职责界限不清晰。
我选择的做法是在 src/test/java
目录下扩展App
子类UnitTestApp
如下。
public class UnitTestApp extends App { @Override public void setupCrashReporting () { } @Override public void setupUmeng () { } @Override protected void setupComponent () { CollectInfoUtil.init (this); initVersionInfo (); } @Override public boolean isMainProcess () { return true; }}
这生产了一个仅测试使用的UnitTestApp
,但是如何测试时使用的是UnitTestApp
,而不是App
。你需要自定义TestRunner
,如下:
public class UnitTestGradleTestRunner extends RobolectricGradleTestRunner { // This value should be changed as soon as Robolectric will support newer api. private static final int SDK_EMULATE_LEVEL = 21; public UnitTestGradleTestRunner (Class<?> klass) throws InitializationError { super (klass); } @Override public Config getConfig (Method method) { final Config defaultConfig = super.getConfig (method); return new Config.Implementation ( new int[]{SDK_EMULATE_LEVEL}, defaultConfig.manifest (), defaultConfig.qualifiers (), defaultConfig.packageName (), defaultConfig.resourceDir (), defaultConfig.assetDir (), defaultConfig.shadows (), UnitTestApp.class, // Here is the trick, we change application class to one with mocks. defaultConfig.libraries (), defaultConfig.constants () == Void.class ? BuildConfig.class : defaultConfig.constants () ); } @NonNull public static UnitTestApp getApp () { return (UnitTestApp) RuntimeEnvironment.application; }}
在你需要使用到App
的测试类中指定如下:
@RunWith (UnitTestGradleTestRunner.class)@Config (constants = BuildConfig.class)public class LoginActivityTest{@Before public void setUp () throws Exception { UnitTestApp app = UnitTestGradleTestRunner.getApp (); Assert.assertNotNull ("shadowApp not null.", app); Assert.assertNotNull ("shadowApp context not null.", app.getApplicationContext ()); }}
其他建议
在测试过程中,经常会需要对测试代码进行 set/get
操作。但是大部分时候,一些方法或者域是private
或者protect
,为了保证测试功能代码的唯一性,我选择使用reflect
方式,来确保测试工作的顺利。我使用的reflection-utils来完成反射工作。
结束语
对robolectric
的基本认识如上,但是具体在测试中很多问题需要逐一解决,后续再一一整理出来。
希望大家多拍砖,特别是有错误的地方重拍都没事~
0 0
- 使用 robolectric 做单元测试
- 使用Robolectric做Android单元测试
- 使用Robolectric进行Android单元测试
- 单元测试Robolectric的使用详解
- 用Robolectric来做Android单元测试
- android robolectric 单元测试的简单使用
- 使用Robolectric对Android应用进行单元测试
- Android单元测试(四):Robolectric框架的使用
- 初试Robolectric进行单元测试
- Android Studio使用Robolectric对android程序实现单元测试
- Android-使用Mockito、Robolectric和RxJava及Retrofit进行单元测试
- Robolectric使用
- Android stuido 集成 Robolectric 单元测试
- 单元测试--Robolectric及代码覆盖率
- 使用DBUnit做单元测试
- 使用xcode5做单元测试
- 使用Nunit做单元测试
- 使用easymock做单元测试
- ssh私钥登陆提示Server refused our key问的解决办法
- 银行卡信息查询
- 图解Android - Zygote, System Server 启动分析
- 多线程开发
- Servlet知识点<一>
- 使用 robolectric 做单元测试
- iOS开发Runtime那些事
- Linux下的sock_stream和sock_dgram
- HDU 4995Revenge of kNN(暴力)
- 罗马数字转换为十进制数字
- Node:Q与node http模块搭配
- Servlet知识点<二>
- 判断一个数是否是2^N次方
- MATLAB 解不等式组