简体   繁体   English

Robolectric 与 Android 测试框架

[英]Robolectric vs Android Test Framework

Does Robolectric provide any clear benefits compared to Android Test Framework ?Android 测试框架相比, Robolectric是否提供任何明显的优势? I've read the docs regarding both the frameworks but as far as i can see the only clear cut benefit regarding Robolectric is that it runs on JVM rather than the DalvikVM, making it faster than Android framework.我已经阅读了关于这两个框架的文档,但据我所知Robolectric唯一明确的好处是它运行在 JVM 而不是 DalvikVM 上,使其比 Android 框架更快。

Are there any other major benefits that stand out ?还有其他突出的主要好处吗?

Update Apr-2015 : Gradle build tools and Android Studio now officially support unit testing and prevent android.jar from throwing stub (no real implementation) error. 2015 年 4 月更新:Gradle 构建工具和 Android Studio现在正式支持单元测试并防止 android.jar 抛出存根(没有真正实现)错误。 So, yes its possible to run tests on Java VM, when stubs are appropriately mocked.所以,是的,当存根被适当地模拟时,它可以在 Java VM 上运行测试。 Its a start but is still not comparable with Robolectric's power.它是一个开始,但仍然无法与 Robolectric 的力量相提并论。 There is also a third alternative, Scroll to bottom of this answer.还有第三种选择,滚动到这个答案的底部。

Now, about Robolectric :现在,关于 Robolectric :

Pros : here are a few points about how it has proved to be useful in unit testing:优点:这里有一些关于它如何被证明在单元测试中有用的要点:

  1. You need not run an emulator, So you can test some of the project's non UI parts without requiring an emulator or device.您不需要运行模拟器,因此您可以测试项目的一些非 UI 部分,而无需模拟器或设备。 This also applies to running tests on continuous integration/ build servers, no emulator instances need be launched.这也适用于在持续集成/构建服务器上运行测试,不需要启动模拟器实例。

  2. With Android Studio, you can quickly run one particular test class, when you are working on the implementation to satisfy the test cases.使用 Android Studio,您可以在执行实现以满足测试用例时快速运行一个特定的测试类。 You can debug as you write code.您可以在编写代码时进行调试。 This is a massive productivity gain.这是一个巨大的生产力提升。

  3. Can fake almost every android related thing as shadow objects, even SQLite.可以将几乎所有与 android 相关的东西都伪装成影子对象,甚至是 SQLite。 Plus each shadow object exposes many useful functions which their normal android counterparts don't offer.此外,每个 shadow 对象都公开了许多它们的普通 android 对应物不提供的有用功能。 With shadow counterparts of android Object, you can do internal checking or call special methods.使用 android 对象的影子对应物,您可以进行内部检查或调用特殊方法。

  4. Really shines when testing multi threaded code like AsyncTask s, Loopers and Handlers etc. You can pause and fast-forward thread Loopers, even main thread.在测试多线程代码(如AsyncTaskLoopersHandlers等)时真的很AsyncTask 。您可以暂停和快进线程 Loopers,甚至主线程。 Excellent for Handler based callback testing.非常适合基于 Handler 的回调测试。

  5. JUnit 4 format supported.支持 JUnit 4 格式。 Android is still holding onto JUnit 3 last time I checked.上次我检查时,Android 仍然坚持使用 JUnit 3。

  6. Can be combined with other test tools like Mockito, Espresso etc etc.可以与其他测试工具结合使用,如 Mockito、Espresso 等。

  7. Supports mock Activity instance creation Robolectric.buildActivity() and its control via ActivityController .支持模拟 Activity 实例创建Robolectric.buildActivity()并通过ActivityController对其进行控制。 Fragment/View manipulation also works on such mock activity instances.片段/视图操作也适用于此类模拟活动实例。

  8. There are now provided add-on modules that cover multi-dex, v4-support, play services, maps and http client as well.现在提供的附加模块涵盖了多 dex、v4 支持、播放服务、地图和 http 客户端。 So, its now easy to test code using these library functions as well.因此,现在也可以轻松地使用这些库函数来测试代码。

Cons : Where I found it not so good:缺点:我发现它不太好:

  1. Robolectric excels at aiding Unit testing, but does not cover all the functionality a real device or emulator can offer. Robolectric 擅长辅助单元测试,但并未涵盖真实设备或模拟器可以提供的所有功能。 For example sensors, gps, open-gl etc etc.例如传感器、gps、open-gl 等。

  2. You'll need an emulator or real device when doing integration or UI testing, so that Activities and services can interact with full android environment (other apps, like using camera app to get a picture for your app), not a limited one.在进行集成或 UI 测试时,您将需要模拟器或真实设备,以便活动和服务可以与完整的 android 环境(其他应用程序,例如使用相机应用程序为您的应用程序获取图片)交互,而不是有限的。 Here you'll need to use the default test framework as it has functions to test UI as well.在这里,您需要使用默认测试框架,因为它也具有测试 UI 的功能。

  3. JNI loading seems not to be supported.似乎不支持 JNI 加载。 So code with native dependency can't be tested.因此无法测试具有本机依赖项的代码。

  4. As of now, Robolectric has a hard wired dependency on google maps jar to work.到目前为止,Robolectric 对谷歌地图 jar 的工作有一个硬连线依赖。 And will download another android.jar from maven.并将从 maven 下载另一个 android.jar。 So, project setup may require a bit of a tinkering.因此,项目设置可能需要一些修补。 Update: as of v3 it seems to pull all dependencies via Gradle without much fuss.更新:从 v3 开始,它似乎毫不费力地通过 Gradle 拉取所有依赖项。

  5. Newer Android tools support coverage and reports generation etc, but only when test are run on a device.较新的 Android 工具支持覆盖率和报告生成等,但仅限于在设备上运行测试时。 So with Robolectric you'll have to create extra Gradle tasks (run Jacoco) to do it for you.因此,使用 Robolectric,您必须创建额外的 Gradle 任务(运行 Jacoco)来为您完成。 Update: Gradle 2.9 + ships with jacoco plugin.更新:Gradle 2.9 + 附带 jacoco 插件。

  6. As both gradle and android build tools are shipping out newer build versions at a fast rate, stable Robolectric versions will sometimes start having problems with the changed build tooling.由于 gradle 和 android 构建工具都在快速发布更新的构建版本,稳定的 Robolectric 版本有时会开始遇到更改构建工具的问题。 Most typical problems include: sdk version incompatible, manifest not found, build output paths mismatch, resources not loading, build config issues etc. Some issues are also related to bugs in android tools.最典型的问题包括:sdk 版本不兼容、找不到清单、构建输出路径不匹配、资源未加载、构建配置问题等。一些问题也与 android 工具中的错误有关。 At times you may even have to write your own custom test runner or apply workarounds till next version fixes those issues.有时您甚至可能需要编写自己的自定义测试运行程序或应用变通方法,直到下一个版本修复这些问题。 Check out open issues and configure tests accordingly.检查未解决的问题并相应地配置测试。


Another alternative is simply mock stuff on your own, no frameworks involved.另一种选择是你自己模拟东西,不涉及框架。 Its the "hard way" but the most customizable way.它是“艰难的方式”,但也是最可定制的方式。 Its plain JUnit with JMockit :它带有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;  
                }
            };
        }};
    }
}

Above is a crude and inline example.以上是一个粗略的内联示例。 You can actually create proper re-usable classes (say FragmentTestHarness ) that will take a component (say a Fragment ) under test and wrap it in completely isolated environment, preparing it for tests.您实际上可以创建适当的可重用类(例如FragmentTestHarness ), FragmentTestHarness将接受测试的组件(例如Fragment )并将其包装在完全隔离的环境中,为测试做好准备。

To share how i do...分享我是怎么做的...

Robolectric For SQL, activities flow, for those objects that needed context. Robolectric 对于 SQL,活动流,对于那些需要上下文的对象。

JUnit4 for api's java module to make sure data are return correctly.用于 api 的 java 模块的 JUnit4 以确保数据正确返回。

Espresso For checking ui display correctly. Espresso 用于检查 ui 显示是否正确。

When I modified api...I only run jUnit4.当我修改 api...我只运行 jUnit4。

When I modified the data binding between api and UI or Sqlite, then I will only run Robolectric.当我修改了api和UI或Sqlite之间的数据绑定时,那么我只会运行Robolectric。

When I modified UI I only run Espresso.当我修改 UI 时,我只运行 Espresso。

Sometimes I will run Robolectric and espresso together, but very rare.有时我会一起运行 Robolectric 和 espresso,但非常罕见。

But I will run all before publish to play store.但我会在发布到 Play 商店之前运行所有内容。

Because I think there is not real benefit for now.因为我认为目前没有真正的好处。 But see how u use it to speed up your product quality and development speed.但是看看你如何使用它来加快你的产品质量和开发速度。

Correct me if I am wrong.如果我错了,请纠正我。

You would use Robolectric only in cases you need to mock or fake the Android framework , eg if you need a context.仅在需要模拟或伪造Android 框架的情况下才使用Robolectric ,例如,如果您需要上下文。 When using the Android Test Framework you would have to run Instrumented tests for that which is ultra slow.使用Android 测试框架时,您必须为超慢的测试运行仪器测试

If you write your tests for letting them run frequently, eg because you follow a tdd approach this is not an option.如果您编写测试是为了让它们频繁运行,例如因为您遵循 tdd 方法,这不是一个选择。 So in this case Robolectric comes in handy.所以在这种情况下, Robolectric就派上用场了。

So the main benefit about Robolectric is that it is a lot faster than Espresso or Instrumented tests in general.因此, Robolectric的主要好处是它比一般的EspressoInstrumented 测试要快得多。

The downside is that it fakes an Android environment which you should be aware of.缺点是它伪造了您应该注意的 Android 环境。 To validate real world problems, better use a classic Android Framework approach.要验证现实世界中的问题,最好使用经典的 Android 框架方法。

The best is still to write your code in a way that you can unit test it and that you don't need a context or any other Android framework dependencies .最好的方式仍然是编写您的代码,您可以对其进行单元测试,并且不需要上下文或任何其他 Android 框架依赖项

Robolectric is getting integrated into the Android Testing Framework since I/O 2018 - check out more at the official Robolectric page and watch this video from I/O 2018自 I/O 2018 以来, Robolectric已被集成到 Android 测试框架中 - 在官方 Robolectric 页面上查看更多信息并观看来自 I/O 2018 的视频

The major benefit of Robolectric is speed. Robolectric 的主要优点是速度。 Unit tests with Robolectric do not require a running emulator or device to run the tests and are thus much much faster.使用 Robolectric 进行单元测试不需要正在运行的模拟器或设备来运行测试,因此速度要快得多。

You might still want to have a suite of integration tests that run against a real device, just a much smaller suite.您可能仍然希望拥有一套针对真实设备运行的集成测试,只是一个小得多的套件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM