public class MyTestRunner extends RobolectricTestRunner {


  public MyTestRunner(Class testClass) throws InitializationError {

  super(testClass, new RobolectricConfig(new File("my_app/AndroidManifest.xml"), new File("my_app/res")));

  }

  }

  有了自己的test runner, 我们可以来写一个简单的Robolectric测试了

  1 @RunWith(MyTestRunner.class)

 

  public class SignInScreenTest {


  @Test

  public void should_start_intent_when_click_registration_button() {


  2 Activity activity = new Activity();


  SignInScreen signInScreen = new SignInSceen(activity);


  3 TextView textView = (TextView) signInScreen.findViewById(R.id.sign_in_registration);


  textView.performClick();


  4 ShadowActivity shadowActivity = Robolectric.shadowOf(activity);


  Intent nextStartedActivity = shadowActivity.getNextStartedActivity();


  ShadowIntent shadowIntent = Robolectric.shadowOf(nextStartedActivity);


  assertThat((Class) shadowIntent.getIntentClass(), equalTo(WebPageActivity.class));

  }

  }

  在这段测试代码中:


  (1)声明了测试运行的test runner;像普通的单元测试,它也分为了set up, method invoke,以及assert三个阶段。


  在(2)中,测试初始化了一个Activity用于提供Context,并使用这个Activity对象生成了一个SignInScreen实例;

 

  第二个阶段,也是(3)中,代码在生成的登录界面中找到注册按钮,并进行点击。为有意思的第三个阶段需要验证注册按钮的点击触发了我们期望的事件,即使用Implicit Intent来打开WebPageActivity。

 

  为了进行这个验证,(4)中首先通过Robolectric的静态方法shadowOf来获取activity对象相应的Shadow Object ,而通过这个Shadow Object,代码获得了activity对象的所开启的Intent对象。后通过Intent对象的Shadow Object ,我们可以获得其intent class并进行验证。

 

  通过这个测试我们可以看到,有了Robolectric的帮助,我们可以轻松的生成Activity实例,加载xml布局文件,进行组件上的方法调用。通过shadow对象,我们则可以获取Android相关类的对象状态信息,来对测试的结果进行验证。实际上除了Intent,我们还可以对通过使用 Robolectric对代码中的Dialog,HTTP请求,数据库操作等各个方面进行测试。


  Robolectric并没有为Android SDK中的所有类都定义shadow对象,你可以通过调用 Robolectric.getDefaultShadowClasses() 方法来查看你所需要的类是否已经被注册到了需要被shadow的类列表中。如果没有你可能需要对其进行定制和扩展。关于如何添加Shadow Objects而增加Robolectric的功能,在Robolectric的网站文档中有详细的描述。

  由于Robolectric的测试是可以脱离Android的SDK运行于JVM上,我们可以像运行普通的jUnit测试一样在IDE中或者在终端使用构建脚本运行我们的测试。

  由于Robolectric的更新并不是很频繁,我们在平时也遇到了一些需要定制的情况,如支持Android4.0,使用sonar进行项目质量分析等等。所以我们在github上fork了Robolectric的工程,并以git submodule的方式将其加入到我们的工程管理中来,这样,我们可以根据自己的需要来对Robolectric进行修改和扩展。由于我们对 Robolectric的修改频率非常的低,在每一次修改后,可以将其编译打包成一个jar文件,将这个jar文件加入到我们的工程管理中,让我们的测试代码仍然依赖于这个jar文件,这样可以免去在运行测试中不必要的对Robolectric的重复编译,加快测试代码的运行速度。

  我们在当前的项目中也进行了一定的关于验收测试方面的尝试,由于测试脚本是开发人员与BA以及QA进行沟通的一种重要途径,也是开发人员和QA进行人工测试的基准,因此我们仍然选用了cucumber作为我们编写脚本的工具,再使用cuke4duke和jRuby对其进行解析和执行。但目前这种测试方式似乎并不成熟,我们在这种尝试和实践的过程中遇到了种种的问题,主要在于测试编写和维护上的困难,这也导致了我们验收测试的覆盖率并不高。我们也会在这一方向上进行更多的尝试,如果大家有更好的关于验收测试自动化方面的实践,也希望能够得到你们的帮助和指正。