Robolectric与Android测试框架

Tra*_*909 47 android robolectric

是否Robolectric可提供比任何明显的好处的Android测试框架?我已经阅读了有关这两个框架的文档,但据我所知,Robolectric唯一明确的好处是它运行在JVM而不是DalvikVM上,使其比Android框架更快.

还有其他突出的主要好处吗?

S.D*_*.D. 78

2015年4月更新:Gradle构建工具和Android Studio 现在正式支持单元测试,并防止android.jar抛出存根(没有真正的实现)错误.所以,是的,当存根被适当地模拟时,它可以在Java VM上运行测试.它是一个开始,但仍然无法与Robolectric的功率相媲美.还有第三种选择,滚动到这个答案的底部.

现在,关于Robolectric:

优点:以下是关于如何证明它在单元测试中有用的几点:

  1. 您无需运行模拟器,因此您可以在不需要模拟器或设备的情况下测试项目的非UI部件.这也适用于在持续集成/构建服务器上运行测试,不需要启动模拟器实例.

  2. 使用Android Studio,您可以在执行实现以满足测试用例时快速运行一个特定的测试类.您可以在编写代码时进行调试.这是一个巨大的生产力增益.

  3. 可以假装几乎每个与android相关的东西都是阴影对象,甚至是SQLite.此外,每个阴影对象都会暴露许多有用的功能,这些功能是普通的Android对手不提供的.使用android Object的阴影对应物,您可以进行内部检查或调用特殊方法.

  4. 测试多线程代码一样,当真正的亮点AsyncTaskS,LoopersHandlers等,您可以暂停和快进线程活套,甚至主线程.非常适合基于Handler的回调测试.

  5. 支持JUnit 4格式.我上次检查时,Android仍然持有JUnit 3.

  6. 可与其他测试工具结合使用,如Mockito,Espresso等.

  7. 支持模拟Activity实例创建Robolectric.buildActivity()及其控制ActivityController.片段/视图操作也适用于此类模拟活动实例.

  8. 现在提供了附加模块,涵盖了多dex,v4支持,播放服务,地图和http客户端.因此,它现在也可以使用这些库函数轻松测试代码.

缺点:我发现它不太好:

  1. Robolectric擅长辅助单元测试,但并未涵盖真实设备或仿真器可提供的所有功能.例如传感器,gps,open-gl等.

  2. 在进行集成或UI测试时,您将需要一个模拟器或真实设备,以便活动和服务可以与完整的Android环境(其他应用程序,如使用相机应用程序为您的应用程序获取图片)进行交互,而不是有限的.在这里,您需要使用默认测试框架,因为它还具有测试UI的功能.

  3. 似乎不支持JNI加载.因此无法测试具有本机依赖性的代码.

  4. 截至目前,Robolectric对谷歌地图jar的硬连线依赖性.并将从maven下载另一个android.jar.因此,项目设置可能需要一些修补.更新:从v3开始,它似乎通过Gradle拉动所有依赖项而不用大惊小怪.

  5. 较新的Android工具支持覆盖范围和报告生成等,但仅限于在设备上运行测试时.因此,使用Robolectric,您将需要创建额外的Gradle任务(运行Jaococ)来为您完成.更新:Gradle 2.9 +附带jacoco插件.

  6. 由于gradle和android构建工具都以较快的速度发布了较新的构建版本,稳定的Robolectric版本有时会开始出现更改的构建工具问题.最典型的问题包括:sdk版本不兼容,清单未找到,构建输出路径不匹配,资源未加载,构建配置问题等.一些问题也与android工具中的错误有关.有时您甚至可能需要编写自己的自定义测试运行器或应用解决方法,直到下一版本修复这些问题.查看未解决的问题并相应地配置测试.


另一个替代方案是自己简单地模拟东西,不涉及任何框架.它是"艰难的方式",但最可定制的方式.它与JMockit的简单JUnit:

@RunWith(JMockit.class)
public class OtherTest {
    public void testHandlerCallback(@Mocked final FragmentTransaction transaction,
                                    @Mocked final FragmentManager manager,
                                    @Mocked final Activity activity,
                                    @Mocked final LayoutInflater inflater,
                                    @Mocked final ViewGroup parent) {

        final List<Fragment> fragments = new ArrayList<>();
        new Expectations() {{
            activity.getFragmentManager(); result = manager;
            manager.beginTransaction(); result = transaction;
            transaction.add(withCapture(fragments), anyString);
            transaction.commit(); result = new Delegate<Void>() {
                public int commit() {
                    View v = fragments.get(0).onCreateView(inflater,parent,null);
                    Deencapsulation.invoke(v,"onMeasure",0,0);
                  return  0;  
                }
            };
        }};
    }
}
Run Code Online (Sandbox Code Playgroud)

以上是粗略的内联示例.实际上,您可以创建适当的可重用类(比如说FragmentTestHarness),这些类将Fragment测试一个组件(比如说a )并将其包装在完全隔离的环境中,为测试做好准备.


Sha*_*hye 25

分享我的做法......

Robolectric对于SQL,活动流程,用于那些需要上下文的对象.

JUnit4用于api的java模块,以确保数据正确返回.

浓咖啡用于正确检查ui显示.

当我修改api ...我只运行jUnit4.

当我修改api和UI或Sqlite之间的数据绑定时,我只会运行Robolectric.

当我修改UI时,我只运行Espresso.

有时我会一起运行Robolectric和浓缩咖啡,但非常罕见.

但是我会在发布之前运行所有商店.

因为我认为现在没有真正的好处.但是看看你如何使用它来加快产品质量和开发速度.

如果我错了,请纠正我.

  • 你有一些样品我可以看一下吗?:D (3认同)

luc*_*ler 7

仅在需要模拟或伪造Android 框架的情况下才使用Robolectric,例如,如果您需要上下文。使用Android 测试框架时,您必须为超慢的测试运行仪器测试

如果您编写测试是为了让它们频繁运行,例如因为您遵循 tdd 方法,这不是一个选择。所以在这种情况下,Robolectric就派上用场了。

因此,Robolectric的主要好处是它比EspressoInstrumented 测试要快得多。

缺点是它伪造了您应该注意的 Android 环境。要验证现实世界中的问题,最好使用经典的 Android 框架方法。

最好的方式仍然是编写您的代码,您可以对其进行单元测试,并且不需要上下文或任何其他 Android 框架依赖项

自 I/O 2018 以来,Robolectric已被集成到 Android 测试框架中 - 在官方 Robolectric 页面上查看更多信息并观看来自 I/O 2018 的视频