Robolectric与Android测试框架

时间:2013-08-16 10:44:05

标签: android robolectric

Android测试框架相比, Robolectric 能否带来明显的好处?我已经阅读了有关这两个框架的文档,但据我所知, Robolectric 唯一明确的好处是它运行在JVM而不是DalvikVM上,使其比Android框架更快。 / p>

还有其他重大好处吗?

4 个答案:

答案 0 :(得分:74)

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

现在,关于Robolectric:

优点:以下是关于它如何在单元测试中发挥作用的几点:

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

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

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

  4. 在测试AsyncTask s,LoopersHandlers等多线程代码时真的很棒。你可以暂停和快进线程Loopers,甚至主线程。非常适合基于处理程序的回调测试。

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

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

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

  8. 现在提供的add-on modules涵盖了多索引,v4支持,播放服务,地图和http客户端。因此,它现在也可以使用这些库函数轻松测试代码。

  9. 缺点:我发现它不太好:

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

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

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

    4. 截至目前,Robolectric依赖谷歌地图jar工作。并将从maven下载另一个android.jar。因此,项目设置可能需要一些修补。 更新:从第3版开始,似乎通过Gradle完全依赖所有依赖项。

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

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


    7. 另一种选择就是单独使用模拟内容,不涉及任何框架。它是“艰难的方式”,但最可定制的方式。其简单的JUnit与JMockit

      @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;  
                      }
                  };
              }};
          }
      }
      

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

答案 1 :(得分:23)

分享我的表现......

Robolectric 对于SQL,活动流向那些需要上下文的对象。

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

咖啡 用于正确检查ui显示。

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

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

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

有时我会一起运行Robolectric和espresso,但非常罕见。

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

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

如果我错了,请纠正我。

答案 2 :(得分:3)

Robolectric的主要优点是速度。使用Robolectric进行单元测试不需要运行仿真器或设备来运行测试,因此速度要快得多。

您可能仍希望拥有一套针对真实设备运行的集成测试,只需要更小的套件。

答案 3 :(得分:0)

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

如果您编写测试以使其能够经常运行,例如因为您遵循tdd方法,所以这不是一种选择。因此,在这种情况下 Robolectric 会派上用场。

因此 Robolectric 的主要优点是,它比 Espresso 仪器测试快很多。

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

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

Robolectric 自I / O 2018以来已集成到Android测试框架中-在official Robolectric page上查看更多内容,并在I / O 2018上观看this video