Android Unit Test Framework
http://pivotal.github.com/robolectric
Follow us on twitter: @robolectric
Wednesday, October 27...
Tyler Schultz
Agile Engineer, Pivotal Labs
Wednesday, October 27, 2010
Talking Points
• Testing Approaches and Alternatives
• How Robolectric works
• How to extend Robolectric
• Workshop - writ...
Pivotal Labs
• Jasmine - Javascript BDD test framework,
@jasminebdd
• Cedar - iOS/Objective-C BDD test
framework, @cedarbd...
Why Unit Test?
Wednesday, October 27, 2010
Pivotal Labs
• www.pivotallabs.com
• San Francisco (Headquarters), NewYork,
Boulder, Singapore
• Primarily Rails - we do m...
java.lang.RuntimeException(“Stub!”)
Wednesday, October 27, 2010
Google has stripped the classes in the android.jar file and
have had all their method bodies replaced with:
throw new Runti...
Additional Android testing challenges
• Many of the classes and methods are final
• Lack of interfaces
• Non public constru...
sfandroid.org members, what have you
been doing?
Wednesday, October 27, 2010
Android Testing
Approaches
Wednesday, October 27, 2010
Android Testing
Approaches
• No Tests! EGAD!
• Android InstrumentationTests/Robotium -
integration style testing of Androi...
Robolectric
Wednesday, October 27, 2010
Robolectric
• Christian Williams wrote the core while
working on projects at Xtreme Labs of
Toronto.ThankYou Xtreme Labs!
...
Robolectric
• Pivotal Labs has forked Xtreme Labs repo,
renamed it to Robolectric, and expanded its
functionality
• We’ve ...
Robolectric
Why use Robolectric?
What makes it so great?
Wednesday, October 27, 2010
Why Use Robolectric
vs.Android Instrumentation Tests?
• Tests Run outside of the emulator in a JVM,
not the DalvikVM
- Run...
Why Use Robolectric
vs.Android Instrumentation Tests?
• Iterate quickly!
• The latest Pivotal Android project is using
Rob...
Why Use Robolectric
vs. POJO lib approach?
• The POJO lib approach leads to code
proliferation, interfaces with multiple
i...
• Mocking frameworks can lead to tests that
are reverse implementation of the code
• Can lead to tests that are hard to re...
Why Use Robolectric?
• Iterate quickly
• Robolectric allows for a black box style of
testing
• Test behavior instead of im...
How does it work?
Google has stripped the classes in the android.jar file and
have had all their method bodies replaced wit...
How does it work?
• Shadow Objects
• View and Resource Loading
Wednesday, October 27, 2010
How does it work?
• Robolectric intercepts the loading of Android classes
under test
• Rewrites the method bodies of Andro...
How does it work?
• Shadows back the Android classes. i.e.
ShadowImageView backs the ImageView class.
• Method calls to th...
How does it work?
• Robolectric parses layout files and builds a
view object tree made of Android view
objects and, of cour...
• RobolectricSample is a project that is setup
to use Robolectric
• http://github.com/pivotal/RobolectricSample
How can I ...
Getting Started with
Robolectric
$ git clone git://github.com/pivotal/
RobolectricSample.git
$ cd RobolectricSample
$ git ...
RobolectricSample
Ant Support
• RobolectricSample provides a build.xml file
which defines a test task
• Useful for Continuou...
Robolectric IDE
support
• RobolectricSample is setup with IntelliJ project
files. We’re using the latest IntelliJ EAP.
• Ec...
RobolectricSample
Project Layout
• RobolectricSample - main Android module
• robolectric - module containing the robolectr...
Robolectric
Writing Tests
Wednesday, October 27, 2010
Writing Tests
...
@RunWith(RobolectricTestRunner.class)
public class MyActivityTest {
@Test
! public void shouldDoWizbangF...
Writing Tests
@Test
public void shouldShowLogoWhenButtonIsPressed() {
Activity activity = new MyActivity();
activity.onCre...
Writing Tests
Dealing with cases where Android classes
do not provide a way to retrieve object state
Wednesday, October 27...
Writing Tests
Accessing the Shadow Object
<ImageView
android:id=”@+id/logo”
android:layout_width=”wrap_content”
android:la...
Shadow Objects
• @RealObject
• __constructor__
• @Implements
• @Implementation
• Robolectric.bindAllShadowClasses()
Wednes...
Shadow Objects
@RealObject
• Robolectric is using reflection to
instantiate the shadow object (default or
no-args construc...
Shadow Objects
@RealObject
@Implements(View.class)
public class ShadowView {
@RealObject private View realView;
private in...
Shadow Objects
• If no shadow class is registered for an
Android class, the Android object’s super
constructor will seek o...
Shadow Objects
__constructor__
• When Robolectric is finished instantiating
the shadow object, it will attempt to invoke
a...
Shadow Objects
__constructor__
public class Intent {
public Intent(String action, Uri uri) {
/* compiled code */
}
...
}
p...
Shadow Objects
@Implements
@Implements(View.class)
public class ShadowView {
@RealObject private View realView;
private in...
Shadow Objects
@Implementation
public class ShadowTextView {
...
@Implementation
public CharSequence getText() {
return te...
Shadow Objects
Robolectric.bindAllShadowClasses()
• Where shadow objects are registered into
Robolectric
• This is a curre...
Robolectric
Roadmap
• Eclipse support
• Simplified setup - robolectric.jar
• continued shadow updates and additions
• reso...
Q & A & Workshop!
• git clone git://github.com/pivotal/
RobolectricSample.git
• Mac users can download the latest IntelliJ...
Upcoming SlideShare
Loading in...5
×

Learn How to Unit Test Your Android Application (with Robolectric)

6,609

Published on

Robolectric is an open source Android unit testing framework that makes it possible to run unit tests against your Android application code outside of the emulator - in the IDE. Robolectric gives you the scaffolding to run your tests quickly so you can make fast iterations and refactor your code with confidence.

** Check out the video for this presentation at marakana.com: http://mrkn.co/f/192 **

This presentation was given at the San Francisco Android User Group on Oct. 26, 2010.

Published in: Technology
1 Comment
3 Likes
Statistics
Notes
  • Hi Guys,

    You can check out the video for this presentation at: http://mrkn.co/f/192

    ...and if you're interested in learning more about Android or open source software, be sure to check out www.marakana.com.

    Cheers!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
6,609
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
168
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide

Learn How to Unit Test Your Android Application (with Robolectric)

  1. 1. Android Unit Test Framework http://pivotal.github.com/robolectric Follow us on twitter: @robolectric Wednesday, October 27, 2010
  2. 2. Tyler Schultz Agile Engineer, Pivotal Labs Wednesday, October 27, 2010
  3. 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. 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
  5. 5. Why Unit Test? Wednesday, October 27, 2010
  6. 6. Pivotal Labs • www.pivotallabs.com • San Francisco (Headquarters), NewYork, Boulder, Singapore • Primarily Rails - we do mobile too! • Agile, XP, Continuos Integration, Pair Programming Wednesday, October 27, 2010
  7. 7. java.lang.RuntimeException(“Stub!”) Wednesday, October 27, 2010
  8. 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. 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
  10. 10. sfandroid.org members, what have you been doing? Wednesday, October 27, 2010
  11. 11. Android Testing Approaches Wednesday, October 27, 2010
  12. 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
  13. 13. Robolectric Wednesday, October 27, 2010
  14. 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. 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
  16. 16. Robolectric Why use Robolectric? What makes it so great? Wednesday, October 27, 2010
  17. 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. 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. 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. 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. 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. 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. 23. How does it work? • Shadow Objects • View and Resource Loading Wednesday, October 27, 2010
  24. 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. 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. 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. 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. 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
  29. 29. RobolectricSample Ant Support • RobolectricSample provides a build.xml file which defines a test task • Useful for Continuous Integration Wednesday, October 27, 2010
  30. 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. 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
  32. 32. Robolectric Writing Tests Wednesday, October 27, 2010
  33. 33. Writing Tests ... @RunWith(RobolectricTestRunner.class) public class MyActivityTest { @Test ! public void shouldDoWizbangFooBar() { ... Tests that reference Android need to be annotated: Wednesday, October 27, 2010
  34. 34. Writing Tests @Test public void shouldShowLogoWhenButtonIsPressed() { Activity activity = new MyActivity(); activity.onCreate(null); ImageView logo = (ImageView) activity.findViewById(R.id.logo); Button button = (Button) activity.findViewById(R.id.button); assertThat(logo.getVisibility(), equalTo(View.GONE)); button.performClick(); assertThat(logo.getVisibility(), equalTo(View.VISIBLE)); } Wednesday, October 27, 2010
  35. 35. Writing Tests Dealing with cases where Android classes do not provide a way to retrieve object state Wednesday, October 27, 2010
  36. 36. Writing Tests Accessing the Shadow Object <ImageView android:id=”@+id/logo” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:src=”@drawable/logo” /> ... @Test public void logoImageViewShouldUseTheLogoDrawable() { ImageView logo = (ImageView) activity.findViewById(R.id.logo); // imageView only provides logo.getDrawable(); ShadowImageView logoShadow = Robolectric.shadowOf(logo); assertThat(logoShadow.resourceId, equalTo(R.drawable.logo)); } Wednesday, October 27, 2010
  37. 37. Shadow Objects • @RealObject • __constructor__ • @Implements • @Implementation • Robolectric.bindAllShadowClasses() Wednesday, October 27, 2010
  38. 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
  39. 39. Shadow Objects @RealObject @Implements(View.class) public class ShadowView { @RealObject private View realView; private int id; ... Wednesday, October 27, 2010
  40. 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. 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. 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
  43. 43. Shadow Objects @Implements @Implements(View.class) public class ShadowView { @RealObject private View realView; private int id; ... Wednesday, October 27, 2010
  44. 44. Shadow Objects @Implementation public class ShadowTextView { ... @Implementation public CharSequence getText() { return text; } ... Wednesday, October 27, 2010
  45. 45. Shadow Objects Robolectric.bindAllShadowClasses() • Where shadow objects are registered into Robolectric • This is a current listing of all the shadow objects provided by Robolectric Wednesday, October 27, 2010
  46. 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. 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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×