Unit Testing with Robolectric
DroidCon Berlin
Danny Preussler, ebay Kleinanzeigen
• Since 2012 Lead Engineer Android @ ebay Kleinanzeigen
• Before Team Lead Mobile Enterprise Solutions @ Cortado
• C++ Developer @ PSI AG • Started career as developer @ Alcatel
• articles in: android360, mobile Technology, Java Magazin
• speaker: Blackberry Developer Conference SF, DroidCons
Believe in mobile
who's that guy?
eBay Kleinanzeigen Android app: • free app • 2 Mio downloads • 176 K Daily UV • 4.1/5 stars
(>6K ratings)
SOLID FOUNDATION
Flughafen Berlin-Brandenburg, Blick in die Abflughalle by Muns CC BY 3.0 http://commons.wikimedia.org/wiki/File:120513-BER-innen.JPG
Raus aus der Garage!
Tidy garage by Bryn Pinzgauer CC 2.0 http://www."ickr.com/photos/12394349@N06/4492572621/in/photostream/
• Junit 4 (out for 6+ years!!) • Use all your utilities (i.e. mocking) • Use your coverage framework • Use CI tools without Android plugins (sonar)
Scyscrapers by elminium, CC 2.0 http://www."ickr.com/photos/lumen850/5461476268/in/photostream/
Pure JUnit?
java.lang.RuntimeException: Stub!
Android Firewall by Uncalno, CC BY 2.0 "ickr.com/photos/uncalno/8538679708
Separate Java and Android Code?
• Android is not Java! • Intent, Bundle, SparseArray, Uri.. not fancy device classes! • Context everywhere • Recreate the System! (interface UI {...} ?)
Great Wall of China (IV) by isawnyu. CC 2.0 http://www."ickr.com/photos/isawnyu/7183821643/in/photostream/
Allows loading of Android Classes in pure Java projects
static Intent createIntent(Context context, String query, String value) { Intent i = new Intent(context, AdListActivity.class); i.putExtra(AppConstants.QUERY, query); i.putExtra(AppConstants.VALUE, queryString); return i; }
@Test public void createIntentForQuery() { Context c = new AdListActivity(); Intent intent = MyActivity.createIntent(c, "key", "value"); assertNotNull(intent); }
In practice (with programs of several thousand lines of code), we haven't discovered any signi!cant di"erences between the two VMs, and we would consider any di"erence to be a bug in one or the other VM.“ https://sites.google.com/site/androiddevtesting/
Is this valid?
static Intent createIntent(Context context, String query, String value) { Intent i = new Intent(context, AdListActivity.class); i.putExtra(AppConstants.QUERY, query); i.putExtra(AppConstants.VALUE, queryString); return i; }
@Test public void createIntentForQuery() { Context c = mock(Context.class); Intent intent = MyActivity.createIntent(c, "key", "value"); assertNotNull(intent); }
what's this mock thing?
Martin Fowler: „test-doubles ... pre-programmed with
expectations “
mocks...
TelephonyManager mgr = mock(TelephonyManager.class); when(mgr.getDeviceId()).thenReturn("123456"); ...
verify(mgr).getDevice();and/or verifyNoMoreInteractions(mgr);
MyPreferences pref = spy(new MyPreferences(ctx)); ...
spys...
verify(pref).saveTitle(same(title)); verify(pref).savePersonalData(anyString());
Let’s do some Magic…
magic by digitlizedchaos, CC 2.0 "ickr.com/photos/digitizedchaos/4889987210/
in/photostream/
@Test public void checkPhoneNumberIsHidden() {
MyActivity activity = new MyActivity(); activity.onCreate(); TextView tv = (TextView) activity.findViewById(R.id.callText); assertEquals(View.GONE, tv.getVisibility());
}
long shadows by Matthew Photography CC 2.0 "ickr.com/photos/21560098@N06/8064387720/in/photostream/
let's talk about shadows...
Dead End - mid by bennylin0724, CC BY 2.0 flickr.com/photos/benny_lin/191393604
2.0
2.0
@Test @Values(qualifiers = "fr-land") public void shouldShowBucolicFrenchLandscape() throws Exception { // ... }
• less shadows, more real code (goal is to remove 99% of shadows)
• since alpha2: support package complete shadow free • aims for sherlock supported, library support • performance boost • Value quali$ers:
Wanna work with us?
eBay Kleinanzeigen
http://goo.gl/3GCJk
mobile.de
http://goo.gl/JYsXM