Friday, April 5, 2013

The Test Lifecycle in 2.0

Starting with Robolectric 2.0 alpha 3, there are some changes in how Robolectric prepares to run your tests.

Finding Your Application

By default, Robolectric first looks in your AndroidManifest.xml for the class to load as your application:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myapp">
  <application android:name=".Application"/>
</manifest>

That will cause a class called com.myapp.Application to be loaded. However, if you create a class with the same name and package, but with "Test" prepended to the class name, Robolectric will load that instead.

package com.myapp;
class TestApplication extends Application {
}

The Application Lifecycle

Robolectric now automatically calls an application's onCreate() method before the test runs, and onTerminate() after the test runs. Note that this a change from earlier versions. If you want to prevent your application's onCreate() method from being called, you can override it in a test class and have it do nothing.

If your test application implements the TestLifecycleApplication interface, it will get called with a few more useful events:

class TestApplication extends Application
    implements TestLifecycleApplication {
  @Override public void beforeTest(Method method) {
  }

  @Override public void prepareTest(Object test) {
  }

  @Override public void afterTest(Method method) {
  }
}

The overall steps taken when running each test, then, are:
  1. Create your application.
  2. Call application.onCreate().
  3. Call application.beforeTest().
  4. Call application.prepareTest().
  5. Run the test.
  6. Call application.onTerminate().
  7. Call application.afterTest().

These changes should make it possible for many people to avoid overriding RobolectricTestRunner altogether. Note that you can still change this by using your own subclass of RobolectricTestRunner, which provides a different TestLifecycle class.

5 comments:

  1. Sweet!

    But any plans to allow simpler tests to avoid dealing with application bootstrap altogether? If all you need is to mock a few of Android's final classes that's a lot of overhead.

    ReplyDelete
    Replies
    1. Yep, good point. We could make it switchable, something like @Config(createApplication = false).

      Regarding test startup time, the biggest cost by far now is reading in all the resource files. I think we'll get a huge win by lazily loading stuff where we can, which is close on the list.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Any progress on either issue here?
      MikiNW

      Delete
  2. A few questions:

    1. Where to find Robolectric 2.0 alpha 3? It doesn't appear to be on maven.
    2. We're working on a relatively new project, is 2.0 alpha 3 stable enough for us to use, or will we constantly be running into weird issues that will be resolved prior to release?
    3. Is 2.0 compatible with junit 4.11? I assume it is but thought I'd ask (while I'm at it).

    ReplyDelete