版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010316858/article/details/70312795
Robolectric的使用的一些坑
Robolectric可以非常方便的模拟Android环境进行单元测试,JUnit只能进行java的单元测试,所以对于想要非真机或者模拟器测试便衍生出来了Robolectric
Github:https://github.com/robolectric/robolectric
集成方式:
添加依赖 :
testCompile 'org.robolectric:robolectric:3.3.2'
在测试包中创建测试类:
@RunWith(RobolectricTestRunner.class)//指定测试环境
@Config(constants = BuildConfig.class)// Android环境下必须指定该内容,非Android即可
public class WelcomeActivityTest {
private ActivityController<WelcomeActivity> activityController;
private WelcomeActivity homeScreenActivity;
@Before
public void setup() {
ActivityLifecycleAnalyzer.setEnabled(false);
activityController = Robolectric.buildActivity(WelcomeActivity.class).create().start().resume().visible();
homeScreenActivity = activityController.get();
homeScreenActivity.findViewById(R.id.btn_welcome_started).performClick();
System.out.println(ShadowToast.getTextOfLatestToast());
}
@Test
public void checkActivityCreated() {
assertNotNull(homeScreenActivity);
}
@After
public void tearDown() {
activityController.pause().stop().destroy();
}
}
上述注解中@Config中可以配置:
- pakcage
- sdk
- manifest
- 等等…
这样就可以进行单元测试了;
坑1:
当Robolectric遇到MultiDex
因为Android方法不能超过65535的限制,所以可以使用MulitDex进行拆分;但是Robolectric是通过反射去调用的目标Activity,所以会导致找不到资源;
解决办法:
testCompile 'org.robolectric:shadows-support-v4:3.3.2'
testCompile 'org.robolectric:shadows-multidex:3.3.2'
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
坑2:
当Robolectric遇到leakcanary
因为Leackcanary是在Activity生命周期中插桩,导致与死循环,单元测试永无止境的执行下去;
解决办法:
ActivityLifecycleAnalyzer.setEnabled(false);
activityController = Robolectric.buildActivity(WelcomeActivity.class).create().start().resume().visible();//在需要buildActivity/SetupActivity前将Leakcanary给enabled
如果在Application中初始化过Leakcanary,需要判断如下:
AndroidDevMetrics.Builder builder = new AndroidDevMetrics.Builder(this)
.enableActivityMetrics(!isRoboUnitTest())//判断是否可以开启,防止与Roboblectric死循环;
.enableDagger2Metrics(false)
.showNotification(true);
AndroidDevMetrics.initWith(builder);
判断代码如下:
/**
* current is RoboUnitTest?
*
* @return true or false
*/
public static boolean isRoboUnitTest() {
return "robolectric".equals(Build.FINGERPRINT);
}
总结
因为单元测试用的比较少,但是为了规范代码且快速改Bug和迭代的话,单元测试是非常好的在后期开发中.记录一下这些坑,以便能帮助大家,因为官网都比较简单,网上大致都是翻译的官网;