The document discusses the Android unit test framework Robolectric. It provides an overview of Robolectric, including how it works by using shadow objects to simulate the Android framework classes, allowing tests to run on a normal JVM. It also covers how to get started with Robolectric by using the sample project, and how to write tests by accessing shadow objects and dealing with classes that don't expose full state.
3. Talking Points
• Testing Approaches and Alternatives
• How Robolectric works
• How to extend Robolectric
• Workshop - write tests & help getting you
setup
Wednesday, October 27, 2010
4. Pivotal Labs
• Jasmine - Javascript BDD test framework,
@jasminebdd
• Cedar - iOS/Objective-C BDD test
framework, @cedarbdd
• Pivotal Tracker - www.pivotaltracker.com
You may have heard of us:
Wednesday, October 27, 2010
8. Google has stripped the classes in the android.jar file and
have had all their method bodies replaced with:
throw new RuntimeException(“Stub!”);
Wednesday, October 27, 2010
9. Additional Android testing challenges
• Many of the classes and methods are final
• Lack of interfaces
• Non public constructors
• static methods
Wednesday, October 27, 2010
12. Android Testing
Approaches
• No Tests! EGAD!
• Android InstrumentationTests/Robotium -
integration style testing of Android apps
• Library of tested POJO’s, referenced from a
non tested Android project
• Mocking framework such as Easy Mock and
Mockito
Wednesday, October 27, 2010
14. Robolectric
• Christian Williams wrote the core while
working on projects at Xtreme Labs of
Toronto.ThankYou Xtreme Labs!
• Robolectric is published under the MIT
license
Wednesday, October 27, 2010
15. Robolectric
• Pivotal Labs has forked Xtreme Labs repo,
renamed it to Robolectric, and expanded its
functionality
• We’ve used Robolectric on several projects
with great success!
Wednesday, October 27, 2010
17. Why Use Robolectric
vs.Android Instrumentation Tests?
• Tests Run outside of the emulator in a JVM,
not the DalvikVM
- Running in a DalvikVM requires dexing,
packaging and installation on an emulator
or device - slow!
- Tests execute quickly in the JVM and
execute slowly on the emulator
Wednesday, October 27, 2010
18. Why Use Robolectric
vs.Android Instrumentation Tests?
• Iterate quickly!
• The latest Pivotal Android project is using
Robolectric boasting 1,047 tests that run in 28
seconds!
Wednesday, October 27, 2010
19. Why Use Robolectric
vs. POJO lib approach?
• The POJO lib approach leads to code
proliferation, interfaces with multiple
implementations - code bloat!
• Robolectric allows for vastly increased test
coverage. Test ALL your code, not just non-
Android code.
Wednesday, October 27, 2010
20. • Mocking frameworks can lead to tests that
are reverse implementation of the code
• Can lead to tests that are hard to read
• Can lead to tests that don’t help refactoring
Why use Robolectric
vs. Mock approach?
Wednesday, October 27, 2010
21. Why Use Robolectric?
• Iterate quickly
• Robolectric allows for a black box style of
testing
• Test behavior instead of implementation
• High test coverage
Wednesday, October 27, 2010
22. How does it work?
Google has stripped the classes in the android.jar file and
have had all their method bodies replaced with:
throw new RuntimeException(“Stub!”);
Wednesday, October 27, 2010
23. How does it work?
• Shadow Objects
• View and Resource Loading
Wednesday, October 27, 2010
24. How does it work?
• Robolectric intercepts the loading of Android classes
under test
• Rewrites the method bodies of Android classes (using
javassist)
• Binds new shadow objects to new Android objects
• The modified Android objects proxy method calls to
the shadow objects
Shadow objects
Wednesday, October 27, 2010
25. How does it work?
• Shadows back the Android classes. i.e.
ShadowImageView backs the ImageView class.
• Method calls to the Android object are proxied to the
shadow object’s method of the same signature, if it
exists.
• Simple implementations giving rudimentary behavior
• State is recorded so it can be verified in tests
Shadow objects
Wednesday, October 27, 2010
26. How does it work?
• Robolectric parses layout files and builds a
view object tree made of Android view
objects and, of course, their shadows.
• Some of the view xml attributes are applied
to the view object (currently applies: id,
visibility, enabled, text, checked, and src)
• Strings, string arrays, and color resources are
parsed loaded too.
View and Resource Loading
Wednesday, October 27, 2010
27. • RobolectricSample is a project that is setup
to use Robolectric
• http://github.com/pivotal/RobolectricSample
How can I get started?
Wednesday, October 27, 2010
28. Getting Started with
Robolectric
$ git clone git://github.com/pivotal/
RobolectricSample.git
$ cd RobolectricSample
$ git submodule update --init
$ android update project -p .
$ ant clean test
These commands are available on the
RobolectricSample README file
Wednesday, October 27, 2010
30. Robolectric IDE
support
• RobolectricSample is setup with IntelliJ project
files. We’re using the latest IntelliJ EAP.
• Eclipse compatibility is currently unknown.
We need help from the community getting
Eclipse support!
• If nothing else, you should be able to use your
favorite tooling to write your code and use
the ant tasks to build and test.
Wednesday, October 27, 2010
31. RobolectricSample
Project Layout
• RobolectricSample - main Android module
• robolectric - module containing the robolectric
test framework (also a git submodule)
• aidl - module containing any aidl files your project
defines
• code - module where application code and tests go
Wednesday, October 27, 2010
38. Shadow Objects
@RealObject
• Robolectric is using reflection to
instantiate the shadow object (default or
no-args constructor)
• Robolectric will inject the Android object
onto shadow object’s fields annotated with
@RealObject
Wednesday, October 27, 2010
40. Shadow Objects
• If no shadow class is registered for an
Android class, the Android object’s super
constructor will seek out a shadow class,
up through the constructor super chain
until one is found.
Wednesday, October 27, 2010
41. Shadow Objects
__constructor__
• When Robolectric is finished instantiating
the shadow object, it will attempt to invoke
a method on the shadow named
__constructor__ that has the same
args as the Android object’s constructor
Wednesday, October 27, 2010
42. Shadow Objects
__constructor__
public class Intent {
public Intent(String action, Uri uri) {
/* compiled code */
}
...
}
public class ShadowIntent {
public void __constructor__(String action,
Uri uri) {
...
}
...
}
Wednesday, October 27, 2010
46. Robolectric
Roadmap
• Eclipse support
• Simplified setup - robolectric.jar
• continued shadow updates and additions
• resource overrides, i.e. hdpi, landscape,
i18n, etc.
Wednesday, October 27, 2010
47. Q & A & Workshop!
• git clone git://github.com/pivotal/
RobolectricSample.git
• Mac users can download the latest IntelliJ EAP
from my machine: http://tschultz.local
• Add a button to the homepage of
RobolectricSample that toggles the visibility of the
robolectric logo. Tests First!
http://pivotal.github.com/robolectric
http://pivotal.github.com/RoblectricSample
twitter: @robolectric
Wednesday, October 27, 2010