Thursday, May 23, 2013

Configuring Robolectric 2.0

In Robolectric 1.x, it was necessary to extend RobolectricTestRunner if you wanted to configure things differently.

From 2.0 on, most configuration can be accomplished using either the @Config annotation or by adding a special file on your classpath.

You can add the @Config annotation to individual test methods, or entire test classes.

If you'd like to apply a configuration to your entire project, create a file called "org.robolectric.Config.properties", and place it on your classpath. If you're using maven, you could put it in src/test/resources.

Example:

@Config(qualifiers="fr-land")
public void shouldDisplayThingsInFrench() {
  ...
}

Configurable values currently include which manifest to use, the SDK level and qualifiers to report, and the list of additional shadows to enable. See the @Config annotation documentation for details.

Also, remember that Robolectric will now look for a test version of your Application class, where you can do additional configuration which used to require subclassing RobolectricTestRunner.

9 comments:

  1. Thanks for providing this blog re configuration. I've been having trouble with the migration from 1.x to 2.x.

    Please provide a custom manifest configuration example. The documentation says "Robolectric will look relative to the current directory." What is the current directory from which I should specify the manifest file (how do I know where it is starting from)? Do I need to include the text "AndroidManifest.xml?"

    ReplyDelete
  2. The approach that ended up working for me was creating a configuration file at the path specified above with this content:

    manifest=./ProjectName/AndroidManifest.xml

    I'm guessing the standard configuration doesn't work for me because of my project structure:

    project/
    -ruby/...
    -android/ProjectName/
    - (standard Android project structure here)

    ReplyDelete
    Replies
    1. I am trying to use this approach and not sure if I need to create a file with exactly "org.robolectric.Config.properties" name and where to put it in my project. Right now I have it placed in my src directory where all my test cases reside. Also, do I need to add this file to my Android.mk ?

      Delete
  3. So, if I understood it correctly a shadow class should be annotated with

    @Config(shadows = ShadowYourClass.class)?

    ReplyDelete
  4. For my class say Log, I created a Shadow class "ShadowLog"

    @Implements(Log.class)
    public static class ShadowLog {
    public static int i(java.lang.String tag, java.lang.String msg) {
    System.err.println("[" + tag + "] " + msg);
    return 0;
    }
    }

    Now should I just say @Config(shadows = ShadowLog.class). How does Robolectric figures out which shadow class to call when I say

    Log.i("LogTest", "log message")

    ReplyDelete
  5. You can take a look at https://github.com/robolectric/robolectric/issues/594. It looks like shadowed objects are not instrumented so in your example method call will not be redirected to the shadow object

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Add the annotation @Config(manifest="../Android_Project_Under_Test/AndroidManifest.xml") in your Test class or create a file org.robolectric.Config.properties in test directory with following information
    manifest=../Android_Project_Under_Test/AndroidManifest.xml

    ReplyDelete
  8. I'm writing a custom shadow for GooglePlayServicesUtil, it contains static state that needs to be cleared up at the end of each test. I don't see a logical hook to provide this. I see that Robolectric.reset() is called from deep within ParallelUniverse but no natural way to provide automatic resetting of Shadows.... how about a @Reset annotation that if present on a shadow will automatically be called from here?

    ReplyDelete