SlideShare uma empresa Scribd logo
1 de 60
A life without
Robolectric
Droidcon 2016
@PreusslerBerlin
3 years ago.....
©UniversalCityStudios
©UniversalCityStudios
3 years ago.....
Back to the future...
©UniversalCityStudios
©UniversalCityStudios
What happened?
©UniversalCityStudios
What’s wrong with Robolectric?
That‘s why we preferred
Robolectric over Emulatur tests
in the first place
©20thCenturyFox
What’s wrong with Robolectric?
©20thCenturyFox
What’s wrong with Robolectric?
©20thCenturyFox
What’s wrong with Robolectric?
• 188 tests:
• With: 4s 809ms
• Without: 1s 746ms
• 531 tests:
• With: 7s 907ms
• Without: 2s 704ms
©20thCenturyFox
What’s wrong with Robolectric?
• Running a single test needs to
be in ms
• TDD bound to test
performance
• We run 3000+ tests
©20thCenturyFox
Tired of issues like
java.lang.NullPointerException
at
org.robolectric.manifest.MetaData.
init(MetaData.java:55)
at
org.robolectric.manifest.AndroidMa
nifest.initMetaData(AndroidManifes
t.java:377)....
?
Don’t spent more time fixing
your test setup
than fixing your app
Sleepy by Tomas; flickr.com/photos/tma/2438467223; CC 2.0
What’s wrong with Robolectric?
• Developers used too much magic
forgot what unit test should be
• Your tests rely on correct 3rd party implementation
• Tests itself became flaky
Android today
• New developers follow MV* patterns
Code is designed to be testable
No need for Robolectric
• Older projects were made with Robolectric
• Projects not designed to be testable have often need for Robolectric
Welcome to Robolectric withdrawal
Day care:
• You have small units
Start removing
@RunWith(RobolectricTestrunner.class)
and we treat the few remaining
ambulant
Long term care:
• You have large units
• Use lots of magic
Mama will keep baby cozy and warm... by Oreste Messina; flickr.com/photos/oremessina/17338964228; CC 2.0
• Before:
Robolectric.buildActivity(
MyActivity.class).start().get()
• Now:
New MyActivity().onStart()
Welcome to Robolectric withdrawal
room to wait by Several seconds; CC 2.0; flickr.com/photos/severalseconds/16549471571; CC 2.0
What about views?
• No one will parse your xml for you!
• when(activity.findViewById(R.id.toolbar))
.thenReturn(mock(Toolbar.class);
• What if class under test?
Spy it:
tested = spy(tested);
DIY Compost Bin: Assembly by WFIU Public Radio; flickr.com/photos/wfiupublicradio/5561442658; CC 2.0
What about views?
assertTrue(
myview.getVisibility() == View.VISIBLE)
What are we actually testing here?
Robolectrics View implementation!
What‘s the default value?
Don‘t test what you don‘t own!
verify(myview).setVisibility(View.VISIBLE))
Wrongside!byJérémyLelièvre;flickr.com/photos/jrmllvr/10887774436;CC2.0
What about Butterknife?
Couldn‘t be more easy:
fields are package protected
@BindView(R.id.title)
TextView title;
Just set them:
tested.title =
mock(TextView.class)
Butter by Joanna Bourne flickr.com/photos/66992990@N00/4819375090; CC 2.0
Testing Parcelation (Before)
@RunWith(RobolectricTestRunner.class)
public class UserTest {
Parcel parcel = Parcel.obtain();
User tested = new User("123", "456");
@Test
public void check_parcel_implementation() {
tested.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
User out = User.CREATOR.createFromParcel(parcel);
assertEquals("123", out.getUser());
assertEquals("456", out.getPassword());
}
Testing Parcelation (After)
Parcel parcel = mock(Parcel.class);
User tested = new User("123", "456");
@Test
public void should_read_from_parcel() {
when(parcel.readString()).thenReturn("123", "456");
User out = User.CREATOR.createFromParcel(parcel);
assertEquals("123", out.getUser());
assertEquals("456", out.getPassword());
}
Testing Parcelation (After)
Parcel parcel = mock(Parcel.class);
User tested = new User("123", "456");
@Test
public void should_write_to_parcel() {
tested.writeToParcel(parcel, 0);
InOrder verifier = inOrder(parcel);
verifier.verify(parcel).writeString("123");
verifier.verify(parcel).writeString("456");
verifier.verifyNoMoreInteractions();
}
Testing Parcelation (Alternative)
Tip 1: move your models AutoParcel
• No need for parcelation tests anymore
• https://github.com/frankiesardo/auto-parcel
Tip 2: move parcelation code to Parceler
• https://github.com/johncarl81/parceler
Parcels by delgrosso; flickr.com/photos/delgrossodotcom/2553424895; CC 2.0
Testing Intent building (Before)
@Test
public void should_create_intent() {
Intent intent = MyActivity.create(
mock(Context.class), deal);
assertEquals(
deal,
intent.getParcelableExtra(“DEAL“));
}
What are we actually testing here?
Robolectrics Intent implementation!
Dont test what you dont own!
Testing Intent building (After)
@Test
public void should_create_intent () {
IntentFactory.instance =
mockIntentFactory();
Intent intent = MyActivity.create(
mock(Context.class), deal);
verify(intent).putExtra(“DEAL", deal);}
@Test
public void should_create_intent () {
IntentFactory.instance =
mockIntentFactory();
Intent intent = MyActivity.create(
mock(Context.class), deal);
verify(intent).putExtra(“DEAL", deal);}
Testing Intent building (After)
class IntentFactory {
public static IntentFactory instance = new IntentFactory();
Intent create(Context ctx, Class<? extends Context> clazz){
return new Intent(ctx, clazz);
}
}
 Call from @After
public static void reset() {
instance = new IntentFactory();
}
Testing Intent building (after)
• Scared of the public instance
?
• Could be private but then
need setter or reflection
• Whom are you afraid of?
Dr. EVIL (Doctor Malito en Austin Powers) by Hersson Piratoba;
Testing intent building (after)
Do you know the rule about
encapsulation and tests?
Uh, no. What rule is that?
Tests trump Encapsulation.
What does that mean?
That means that tests win.
No test can be denied access to a variable
simply to maintain encapsulation.
Uncle Bob
https://blog.8thlight.com/uncle-bob/2015/06/30/the-little-
singleton.html
Why so serious? by SYD, MsSaraKelly;
flickr.com/photos/mssarakelly/14403017054, CC 2.0
If you still dont like it..
package protected and move mocking to a class in test in same package:
public class IntentFactoryMock {
public static void mockFactory(Intent intent) {
IntentFactory.instance = mockIntentFactory(intent);
}
public static void reset() {
IntentFactory.instance = new IntentFactory();
}
private static IntentFactory mockIntentFactory(Intent intent) {
IntentFactory factory = mock(IntentFactory.class);
when(factory.create()).thenReturn(intent);
Testing intent building (alternative)
• Check out Dart and Henson:
https://medium.com/groupon-
eng/better-android-intents-with-dart-
henson-1ca91793944b#.c7agm3ikh
Navigation
FragmentManager fragmentManager = mock(FragmentManager.class);
when(fragmentManager.beginTransaction()).thenReturn(transaction);
when(transaction.replace(anyInt(),
any(Fragment.class))).thenReturn(transaction);
when(transaction.replace(anyInt(), any(Fragment.class),
anyString())).thenReturn(transaction);
when(transaction.remove(any(Fragment.class))).thenReturn(transaction);
when(transaction.addToBackStack(anyString())).thenReturn(transaction);
when(transaction.add(anyInt(),
any(Fragment.class))).thenReturn(transaction);
when(transaction.add(anyInt(), any(Fragment.class),
anyString())).thenReturn(transaction);
when(transaction.setCustomAnimations(anyInt(),
anyInt())).thenReturn(transaction);
when(transaction.setCustomAnimations(anyInt(), anyInt(), anyInt(),
anyInt())).thenReturn(transaction);
Mocking fragment transactions sucks
Navigation by Marcus Ramberg; flickr.com/photos/marcusramberg/71281972; CC 2.0
Navigation by Marcus Ramberg; flickr.com/photos/marcusramberg/71281972; CC 2.0
Navigation
• Wrap navigation into a component:
@Inject
public Interactor(FragmentTransactionsUtil util)
{...}
util.addAllowingStateLoss(
getFragmengManager(), R.id.content,
MyFragment.create());
Dagger, Butterknife & co.
• Don‘t use Dagger in unit tests!
• Call the constructor yourself
Constructor injection is the only one you should use
• For activites, services, fragment with @Inject fields:
Set the instances directly, package protected!
• KISS: Keep it simple stupid!
Dagger, Butterknife & co.
• Never use Dagger.inject() and co directly!
• Wrap it
• Replace them in tests!
public final class Dependencies {
private static Injector instance = new DaggerInjector();
private static ViewBinder viewBinder = new ViewBinderWithButterknife();
private static ExtraBinder extraBinder = new ExtraBinderWithDart();
public static void bind(Activity activity) {...}
...
Butter your tests...
• Introducing Diacetyl
• ... is added to some foods to impart
its buttery flavor (wikipedia)
• It adds artifical butter flavor to your
Butterknife in test environments.
Pam Cooking Spray, Butter by Mike Mozart; flickr.com/photos/jeepersmedia/15203456322; CC 2.0
Butter your tests...
class MyButterKnifeActivity {
@Bind TextView textView;
@Bind EditText editText;
...
class MyButterKnifeActivityTest {
@Test
public void test() {
MyButterKnifeActivtiy tested = new
MyButterKnifeActivtiy();
Diacetyl.butterForTests(tested);
Pam Cooking Spray, Butter by Mike Mozart; flickr.com/photos/jeepersmedia/15203456322; CC 2.0
Butter your tests...
https://github.com/dpreussler/Diacetyl
Pam Cooking Spray, Butter by Mike Mozart; flickr.com/photos/jeepersmedia/15203456322; CC 2.0
Version checks
public boolean isRTL() {
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.JELLY_BEAN_MR1) {
return resources.getConfiguration()
.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
}
return false;
}
Version checks (Before)
@Test
@Config(reportSdk = 16)
public void returns_false_on_pre_jellybeans() {
Resources resources =
Robolectric.buildActivity(Activity.class)
.get().getResources();
RTLUtil tested = new RTLUtil(resources);
assertFalse(tested.isRTL());
}
Version checks
• Use reflection?
*github.com/dpreussler/SuperReflect
Reflect.on(
Build.VERSION.class)
.set("SDK_INT", 14);
Better:
wrap all the things!
Reflection by Anderson Mancini; flickr.com/photos/ektogamat/3052020494; CC 2.0
Version checks (After)
public boolean isRTL() {
if (AndroidVersions.isMinJellyBeanMR1()) {
return resources
.getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
}
return false;
}
Version checks
@Test
public void returns_false_on_pre_jelly_beans() {
AndroidVersions.VERSION = 16;
Resources resources = mockResources();
RTLUtil tested = new RTLUtil(resources);
assertFalse(tested.isRTL());
verifyZeroInteractions(resources);
}
Version checks
public final class AndroidVersions {
public static int VERSION = Build.VERSION.SDK_INT;
public static boolean isMinJellyBean() {
return VERSION >= Build.VERSION_CODES.JELLY_BEAN;
}
...
}
 Call from @After
public static void reset() {
VERSION = Build.VERSION.SDK_INT;
}
Testing asynchronicity
• Robolectric.flushBackgroundThreadScheduler()
• ShadowApplication.runBackgroundTasks();
•This is wrong!
• Just override runOnUiThread() instead!
Rollercoaster by Eric; flickr.com/photos/eric-omba/481762682; CC 2.0
Testing asynchronicity (Before)
MyActivity activity =
Robolectric.buildActivity(MyActivity.class).get();
activity.doThingInBackground();
Robolectric.getForegroundThreadScheduler()
.advanceToNextPostedRunnable();
// check what happened in runnable
Testing asynchronicity (After)
MyActivity activity = spy(new MyActivity());
ArgumentCaptor<Runnable> captor =
ArgumentCaptor.forClass(Runnable.class);
activity.doThingInBackground();
verify(activity).runOnUiThread(captor.capture());
captor.getValue().run();
... Tip: split into 2 tests:
• verify(activity).runOnUiThread(anyRunnable())
• and the captor one that does the action
Testing asynchronicity
„Always wrap the system clock,
so it can be easily substituted
for testing“
(Martin Fowler)
http://martinfowler.com/articles/nonDeterminism.html#Time
Rollercoaster by Eric; flickr.com/photos/eric-omba/481762682; CC 2.0
Problem: Libraries
• Support libraries
• Third party libraries
• Implementation not
empty,
Run real code on tests
Delivery by Bill; flickr.com/photos/34639780@N07/16480925469; CC 2.0
Problem: Libraries
Example:
• Fragment:onStart
is empty
• SupportFragment:onStart
actually does things
Delivery by Bill; flickr.com/photos/34639780@N07/16480925469; CC 2.0
Problem: Libraries
• Needs more mocking
• Might need Reflection work
• Tricky on constructors
i.e. custom views extends
„empty“ android views
Delivery by Bill; flickr.com/photos/34639780@N07/16480925469; CC 2.0
Libraries (Reflection needed)
CredentialsApi realApi = Auth.CredentialsApi;
CredentialsApi apiMock = mock(CredentialsApi.class);
SuperReflect.on(Auth.class).set("CredentialsApi", apiMock);
...
tested.onConnected(mockBundle());
verify(apiMock).request(
any(GoogleApiClient.class), any(CredentialRequest.class));
@After
public void tearDown() {
SuperReflect.on(Auth.class).set("CredentialsApi", realApi);
}
Write it nicer
• mockView() instead of mock(View.class)
...
• mockEditText(„test“)that implements Editable
• mockFragmentTransaction() that returns self while building
• mockRecyclerView() that remembers adapter
https://github.com/dpreussler/mockitoid
rainbow revisited by Bill Rosgen; flickr.com/photos/wrosgen/4706169184; CC 2.0
Write it nicer
• anyActivity() instead of any(Activity.class)
• anyContext()...
• anyView()...
https://github.com/dpreussler/mockitoid
rainbow revisited by Bill Rosgen; flickr.com/photos/wrosgen/4706169184; CC 2.0
Gradually stop your addiction
Subscription: Unmock
Decide in gradle which classes
you still need from Robolectric
https://github.com/bjoernQ/unmock-plugin
Any reasons to stick to Robolectric?
“I need to test lots of UI”
Test with mocks!
“My tests are testing a complete flow”
Your tests are too big
“My tests depend on resources”
Integration test? Move to Espresso?
Any reasons to stick to Robolectric?
“I want to test my SqlLiteOpenhelper with a real database?”
Wrap SqlLiteopenHelper!
Assert Query Strings
(Use a java version of SQLlite if you real queries)
No reason!
And often smell for bad code design! Fix the
code not the test!
Groupon is Mobile
One of worlds most popular apps
> 50 Mio android downloads
Unit testing by developers
> 2000 unit test for Consumer app
> 3000 unit tests for Merchant app
Automation by QA engineers
RoboRemote for Consumer app
Appium for Merchant app
Danny Preussler
@PreusslerBerlin
ThankYoubyNateGrigg;
www.flickr.com/photos/nateone/3768979925,CC2.0

Mais conteúdo relacionado

Mais procurados

Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistAnton Arhipov
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Anton Arhipov
 
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingJEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Omar Miatello
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......hugo lu
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limitsDroidcon Berlin
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentSchalk Cronjé
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 

Mais procurados (20)

Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
GMock framework
GMock frameworkGMock framework
GMock framework
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
droidparts
droidpartsdroidparts
droidparts
 
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingJEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Java 7 LavaJUG
Java 7 LavaJUGJava 7 LavaJUG
Java 7 LavaJUG
 
JS and patterns
JS and patternsJS and patterns
JS and patterns
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
 
groovy & grails - lecture 7
groovy & grails - lecture 7groovy & grails - lecture 7
groovy & grails - lecture 7
 

Destaque

Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinKai Koenig
 
Add ClassyShark to your Android toolbox
Add ClassyShark to your Android toolboxAdd ClassyShark to your Android toolbox
Add ClassyShark to your Android toolboxBoris Farber
 
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Danny Preussler
 
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With RobolectricDanny Preussler
 
The Next Step for Reactive Android Programming
The Next Step for Reactive Android ProgrammingThe Next Step for Reactive Android Programming
The Next Step for Reactive Android ProgrammingTomasz Polanski
 
Creating Gradle Plugins - Oredev
Creating Gradle Plugins - OredevCreating Gradle Plugins - Oredev
Creating Gradle Plugins - OredevAnnyce Davis
 
A realtime infrastructure for Android apps: Firebase may be what you need..an...
A realtime infrastructure for Android apps: Firebase may be what you need..an...A realtime infrastructure for Android apps: Firebase may be what you need..an...
A realtime infrastructure for Android apps: Firebase may be what you need..an...Alessandro Martellucci
 
Developing Apps for Emerging Markets
Developing Apps for Emerging MarketsDeveloping Apps for Emerging Markets
Developing Apps for Emerging MarketsAnnyce Davis
 
Develop Maintainable Apps - edUiConf
Develop Maintainable Apps - edUiConfDevelop Maintainable Apps - edUiConf
Develop Maintainable Apps - edUiConfAnnyce Davis
 
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016Danny Preussler
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기Jongwook Choi
 
MVVM and RxJava – the perfect mix
MVVM and RxJava – the perfect mixMVVM and RxJava – the perfect mix
MVVM and RxJava – the perfect mixFlorina Muntenescu
 
2016 FunctionCup 풀이
2016 FunctionCup 풀이2016 FunctionCup 풀이
2016 FunctionCup 풀이geunwoo bae
 
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Mastering the NDK with Android Studio 2.0 and the gradle-experimental pluginMastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Mastering the NDK with Android Studio 2.0 and the gradle-experimental pluginXavier Hallade
 

Destaque (14)

Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with Kotlin
 
Add ClassyShark to your Android toolbox
Add ClassyShark to your Android toolboxAdd ClassyShark to your Android toolbox
Add ClassyShark to your Android toolbox
 
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
 
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With Robolectric
 
The Next Step for Reactive Android Programming
The Next Step for Reactive Android ProgrammingThe Next Step for Reactive Android Programming
The Next Step for Reactive Android Programming
 
Creating Gradle Plugins - Oredev
Creating Gradle Plugins - OredevCreating Gradle Plugins - Oredev
Creating Gradle Plugins - Oredev
 
A realtime infrastructure for Android apps: Firebase may be what you need..an...
A realtime infrastructure for Android apps: Firebase may be what you need..an...A realtime infrastructure for Android apps: Firebase may be what you need..an...
A realtime infrastructure for Android apps: Firebase may be what you need..an...
 
Developing Apps for Emerging Markets
Developing Apps for Emerging MarketsDeveloping Apps for Emerging Markets
Developing Apps for Emerging Markets
 
Develop Maintainable Apps - edUiConf
Develop Maintainable Apps - edUiConfDevelop Maintainable Apps - edUiConf
Develop Maintainable Apps - edUiConf
 
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
 
MVVM and RxJava – the perfect mix
MVVM and RxJava – the perfect mixMVVM and RxJava – the perfect mix
MVVM and RxJava – the perfect mix
 
2016 FunctionCup 풀이
2016 FunctionCup 풀이2016 FunctionCup 풀이
2016 FunctionCup 풀이
 
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Mastering the NDK with Android Studio 2.0 and the gradle-experimental pluginMastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
 

Semelhante a Unit testing without Robolectric, Droidcon Berlin 2016

Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptSeok-joon Yun
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloadedcbeyls
 
Alexey Buzdin "Maslow's Pyramid of Android Testing"
Alexey Buzdin "Maslow's Pyramid of Android Testing"Alexey Buzdin "Maslow's Pyramid of Android Testing"
Alexey Buzdin "Maslow's Pyramid of Android Testing"IT Event
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mockskenbot
 
少し幸せになる技術
少し幸せになる技術少し幸せになる技術
少し幸せになる技術kamedon39
 
Mastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for JavaMastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for JavaDenilson Nastacio
 
Android testing
Android testingAndroid testing
Android testingSean Tsai
 
Introduction to Testcontainers
Introduction to TestcontainersIntroduction to Testcontainers
Introduction to TestcontainersVMware Tanzu
 
Guide to the jungle of testing frameworks
Guide to the jungle of testing frameworksGuide to the jungle of testing frameworks
Guide to the jungle of testing frameworksTomáš Kypta
 
Testing microservices: Tools and Frameworks
Testing microservices: Tools and FrameworksTesting microservices: Tools and Frameworks
Testing microservices: Tools and FrameworksPiotr Mińkowski
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Java design patterns
Java design patternsJava design patterns
Java design patternsShawn Brito
 
droidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin Coroutinesdroidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin CoroutinesArthur Nagy
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonbeITconference
 
谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testabilitydrewz lin
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42Yevhen Bobrov
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesFranco Lombardo
 

Semelhante a Unit testing without Robolectric, Droidcon Berlin 2016 (20)

Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloaded
 
Alexey Buzdin "Maslow's Pyramid of Android Testing"
Alexey Buzdin "Maslow's Pyramid of Android Testing"Alexey Buzdin "Maslow's Pyramid of Android Testing"
Alexey Buzdin "Maslow's Pyramid of Android Testing"
 
Testing in android
Testing in androidTesting in android
Testing in android
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
少し幸せになる技術
少し幸せになる技術少し幸せになる技術
少し幸せになる技術
 
Mastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for JavaMastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for Java
 
Android testing
Android testingAndroid testing
Android testing
 
Introduction to Testcontainers
Introduction to TestcontainersIntroduction to Testcontainers
Introduction to Testcontainers
 
Guide to the jungle of testing frameworks
Guide to the jungle of testing frameworksGuide to the jungle of testing frameworks
Guide to the jungle of testing frameworks
 
Testing microservices: Tools and Frameworks
Testing microservices: Tools and FrameworksTesting microservices: Tools and Frameworks
Testing microservices: Tools and Frameworks
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
 
droidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin Coroutinesdroidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin Coroutines
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
 
谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutines
 

Mais de Danny Preussler

We aint got no time - Droidcon Nairobi
We aint got no time - Droidcon NairobiWe aint got no time - Droidcon Nairobi
We aint got no time - Droidcon NairobiDanny Preussler
 
Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Danny Preussler
 
TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)Danny Preussler
 
TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)Danny Preussler
 
Junit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behindJunit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behindDanny Preussler
 
All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...Danny Preussler
 
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016Danny Preussler
 
Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)Danny Preussler
 
Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)Danny Preussler
 
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, BerlinAbgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, BerlinDanny Preussler
 
Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)Danny Preussler
 
Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)Danny Preussler
 

Mais de Danny Preussler (12)

We aint got no time - Droidcon Nairobi
We aint got no time - Droidcon NairobiWe aint got no time - Droidcon Nairobi
We aint got no time - Droidcon Nairobi
 
Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)
 
TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)
 
TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)
 
Junit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behindJunit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behind
 
All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...
 
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
 
Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)
 
Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)
 
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, BerlinAbgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
 
Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)
 
Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)
 

Último

Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxpranjaldaimarysona
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls in Nagpur High Profile
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingrakeshbaidya232001
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCollege Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCall Girls in Nagpur High Profile
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlysanyuktamishra911
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...ranjana rawat
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)simmis5
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Christo Ananth
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduitsrknatarajan
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 

Último (20)

Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptx
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writing
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCollege Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduits
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 

Unit testing without Robolectric, Droidcon Berlin 2016

  • 1. A life without Robolectric Droidcon 2016 @PreusslerBerlin
  • 5. Back to the future... ©UniversalCityStudios
  • 8. What’s wrong with Robolectric? That‘s why we preferred Robolectric over Emulatur tests in the first place ©20thCenturyFox
  • 9. What’s wrong with Robolectric? ©20thCenturyFox
  • 10. What’s wrong with Robolectric? ©20thCenturyFox
  • 11.
  • 12. What’s wrong with Robolectric? • 188 tests: • With: 4s 809ms • Without: 1s 746ms • 531 tests: • With: 7s 907ms • Without: 2s 704ms ©20thCenturyFox
  • 13. What’s wrong with Robolectric? • Running a single test needs to be in ms • TDD bound to test performance • We run 3000+ tests ©20thCenturyFox
  • 14. Tired of issues like java.lang.NullPointerException at org.robolectric.manifest.MetaData. init(MetaData.java:55) at org.robolectric.manifest.AndroidMa nifest.initMetaData(AndroidManifes t.java:377).... ? Don’t spent more time fixing your test setup than fixing your app Sleepy by Tomas; flickr.com/photos/tma/2438467223; CC 2.0
  • 15. What’s wrong with Robolectric? • Developers used too much magic forgot what unit test should be • Your tests rely on correct 3rd party implementation • Tests itself became flaky
  • 16. Android today • New developers follow MV* patterns Code is designed to be testable No need for Robolectric • Older projects were made with Robolectric • Projects not designed to be testable have often need for Robolectric
  • 17. Welcome to Robolectric withdrawal Day care: • You have small units Start removing @RunWith(RobolectricTestrunner.class) and we treat the few remaining ambulant Long term care: • You have large units • Use lots of magic Mama will keep baby cozy and warm... by Oreste Messina; flickr.com/photos/oremessina/17338964228; CC 2.0
  • 18. • Before: Robolectric.buildActivity( MyActivity.class).start().get() • Now: New MyActivity().onStart() Welcome to Robolectric withdrawal room to wait by Several seconds; CC 2.0; flickr.com/photos/severalseconds/16549471571; CC 2.0
  • 19. What about views? • No one will parse your xml for you! • when(activity.findViewById(R.id.toolbar)) .thenReturn(mock(Toolbar.class); • What if class under test? Spy it: tested = spy(tested); DIY Compost Bin: Assembly by WFIU Public Radio; flickr.com/photos/wfiupublicradio/5561442658; CC 2.0
  • 20. What about views? assertTrue( myview.getVisibility() == View.VISIBLE) What are we actually testing here? Robolectrics View implementation! What‘s the default value? Don‘t test what you don‘t own! verify(myview).setVisibility(View.VISIBLE)) Wrongside!byJérémyLelièvre;flickr.com/photos/jrmllvr/10887774436;CC2.0
  • 21. What about Butterknife? Couldn‘t be more easy: fields are package protected @BindView(R.id.title) TextView title; Just set them: tested.title = mock(TextView.class) Butter by Joanna Bourne flickr.com/photos/66992990@N00/4819375090; CC 2.0
  • 22. Testing Parcelation (Before) @RunWith(RobolectricTestRunner.class) public class UserTest { Parcel parcel = Parcel.obtain(); User tested = new User("123", "456"); @Test public void check_parcel_implementation() { tested.writeToParcel(parcel, 0); parcel.setDataPosition(0); User out = User.CREATOR.createFromParcel(parcel); assertEquals("123", out.getUser()); assertEquals("456", out.getPassword()); }
  • 23. Testing Parcelation (After) Parcel parcel = mock(Parcel.class); User tested = new User("123", "456"); @Test public void should_read_from_parcel() { when(parcel.readString()).thenReturn("123", "456"); User out = User.CREATOR.createFromParcel(parcel); assertEquals("123", out.getUser()); assertEquals("456", out.getPassword()); }
  • 24. Testing Parcelation (After) Parcel parcel = mock(Parcel.class); User tested = new User("123", "456"); @Test public void should_write_to_parcel() { tested.writeToParcel(parcel, 0); InOrder verifier = inOrder(parcel); verifier.verify(parcel).writeString("123"); verifier.verify(parcel).writeString("456"); verifier.verifyNoMoreInteractions(); }
  • 25. Testing Parcelation (Alternative) Tip 1: move your models AutoParcel • No need for parcelation tests anymore • https://github.com/frankiesardo/auto-parcel Tip 2: move parcelation code to Parceler • https://github.com/johncarl81/parceler Parcels by delgrosso; flickr.com/photos/delgrossodotcom/2553424895; CC 2.0
  • 26. Testing Intent building (Before) @Test public void should_create_intent() { Intent intent = MyActivity.create( mock(Context.class), deal); assertEquals( deal, intent.getParcelableExtra(“DEAL“)); } What are we actually testing here? Robolectrics Intent implementation! Dont test what you dont own!
  • 27. Testing Intent building (After) @Test public void should_create_intent () { IntentFactory.instance = mockIntentFactory(); Intent intent = MyActivity.create( mock(Context.class), deal); verify(intent).putExtra(“DEAL", deal);} @Test public void should_create_intent () { IntentFactory.instance = mockIntentFactory(); Intent intent = MyActivity.create( mock(Context.class), deal); verify(intent).putExtra(“DEAL", deal);}
  • 28. Testing Intent building (After) class IntentFactory { public static IntentFactory instance = new IntentFactory(); Intent create(Context ctx, Class<? extends Context> clazz){ return new Intent(ctx, clazz); } }  Call from @After public static void reset() { instance = new IntentFactory(); }
  • 29. Testing Intent building (after) • Scared of the public instance ? • Could be private but then need setter or reflection • Whom are you afraid of? Dr. EVIL (Doctor Malito en Austin Powers) by Hersson Piratoba;
  • 30. Testing intent building (after) Do you know the rule about encapsulation and tests? Uh, no. What rule is that? Tests trump Encapsulation. What does that mean? That means that tests win. No test can be denied access to a variable simply to maintain encapsulation. Uncle Bob https://blog.8thlight.com/uncle-bob/2015/06/30/the-little- singleton.html Why so serious? by SYD, MsSaraKelly; flickr.com/photos/mssarakelly/14403017054, CC 2.0
  • 31. If you still dont like it.. package protected and move mocking to a class in test in same package: public class IntentFactoryMock { public static void mockFactory(Intent intent) { IntentFactory.instance = mockIntentFactory(intent); } public static void reset() { IntentFactory.instance = new IntentFactory(); } private static IntentFactory mockIntentFactory(Intent intent) { IntentFactory factory = mock(IntentFactory.class); when(factory.create()).thenReturn(intent);
  • 32. Testing intent building (alternative) • Check out Dart and Henson: https://medium.com/groupon- eng/better-android-intents-with-dart- henson-1ca91793944b#.c7agm3ikh
  • 33. Navigation FragmentManager fragmentManager = mock(FragmentManager.class); when(fragmentManager.beginTransaction()).thenReturn(transaction); when(transaction.replace(anyInt(), any(Fragment.class))).thenReturn(transaction); when(transaction.replace(anyInt(), any(Fragment.class), anyString())).thenReturn(transaction); when(transaction.remove(any(Fragment.class))).thenReturn(transaction); when(transaction.addToBackStack(anyString())).thenReturn(transaction); when(transaction.add(anyInt(), any(Fragment.class))).thenReturn(transaction); when(transaction.add(anyInt(), any(Fragment.class), anyString())).thenReturn(transaction); when(transaction.setCustomAnimations(anyInt(), anyInt())).thenReturn(transaction); when(transaction.setCustomAnimations(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(transaction); Mocking fragment transactions sucks Navigation by Marcus Ramberg; flickr.com/photos/marcusramberg/71281972; CC 2.0
  • 34. Navigation by Marcus Ramberg; flickr.com/photos/marcusramberg/71281972; CC 2.0 Navigation • Wrap navigation into a component: @Inject public Interactor(FragmentTransactionsUtil util) {...} util.addAllowingStateLoss( getFragmengManager(), R.id.content, MyFragment.create());
  • 35. Dagger, Butterknife & co. • Don‘t use Dagger in unit tests! • Call the constructor yourself Constructor injection is the only one you should use • For activites, services, fragment with @Inject fields: Set the instances directly, package protected! • KISS: Keep it simple stupid!
  • 36. Dagger, Butterknife & co. • Never use Dagger.inject() and co directly! • Wrap it • Replace them in tests! public final class Dependencies { private static Injector instance = new DaggerInjector(); private static ViewBinder viewBinder = new ViewBinderWithButterknife(); private static ExtraBinder extraBinder = new ExtraBinderWithDart(); public static void bind(Activity activity) {...} ...
  • 37. Butter your tests... • Introducing Diacetyl • ... is added to some foods to impart its buttery flavor (wikipedia) • It adds artifical butter flavor to your Butterknife in test environments. Pam Cooking Spray, Butter by Mike Mozart; flickr.com/photos/jeepersmedia/15203456322; CC 2.0
  • 38. Butter your tests... class MyButterKnifeActivity { @Bind TextView textView; @Bind EditText editText; ... class MyButterKnifeActivityTest { @Test public void test() { MyButterKnifeActivtiy tested = new MyButterKnifeActivtiy(); Diacetyl.butterForTests(tested); Pam Cooking Spray, Butter by Mike Mozart; flickr.com/photos/jeepersmedia/15203456322; CC 2.0
  • 39. Butter your tests... https://github.com/dpreussler/Diacetyl Pam Cooking Spray, Butter by Mike Mozart; flickr.com/photos/jeepersmedia/15203456322; CC 2.0
  • 40. Version checks public boolean isRTL() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { return resources.getConfiguration() .getLayoutDirection() == LAYOUT_DIRECTION_RTL; } return false; }
  • 41. Version checks (Before) @Test @Config(reportSdk = 16) public void returns_false_on_pre_jellybeans() { Resources resources = Robolectric.buildActivity(Activity.class) .get().getResources(); RTLUtil tested = new RTLUtil(resources); assertFalse(tested.isRTL()); }
  • 42. Version checks • Use reflection? *github.com/dpreussler/SuperReflect Reflect.on( Build.VERSION.class) .set("SDK_INT", 14); Better: wrap all the things! Reflection by Anderson Mancini; flickr.com/photos/ektogamat/3052020494; CC 2.0
  • 43. Version checks (After) public boolean isRTL() { if (AndroidVersions.isMinJellyBeanMR1()) { return resources .getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; } return false; }
  • 44. Version checks @Test public void returns_false_on_pre_jelly_beans() { AndroidVersions.VERSION = 16; Resources resources = mockResources(); RTLUtil tested = new RTLUtil(resources); assertFalse(tested.isRTL()); verifyZeroInteractions(resources); }
  • 45. Version checks public final class AndroidVersions { public static int VERSION = Build.VERSION.SDK_INT; public static boolean isMinJellyBean() { return VERSION >= Build.VERSION_CODES.JELLY_BEAN; } ... }  Call from @After public static void reset() { VERSION = Build.VERSION.SDK_INT; }
  • 46. Testing asynchronicity • Robolectric.flushBackgroundThreadScheduler() • ShadowApplication.runBackgroundTasks(); •This is wrong! • Just override runOnUiThread() instead! Rollercoaster by Eric; flickr.com/photos/eric-omba/481762682; CC 2.0
  • 47. Testing asynchronicity (Before) MyActivity activity = Robolectric.buildActivity(MyActivity.class).get(); activity.doThingInBackground(); Robolectric.getForegroundThreadScheduler() .advanceToNextPostedRunnable(); // check what happened in runnable
  • 48. Testing asynchronicity (After) MyActivity activity = spy(new MyActivity()); ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); activity.doThingInBackground(); verify(activity).runOnUiThread(captor.capture()); captor.getValue().run(); ... Tip: split into 2 tests: • verify(activity).runOnUiThread(anyRunnable()) • and the captor one that does the action
  • 49. Testing asynchronicity „Always wrap the system clock, so it can be easily substituted for testing“ (Martin Fowler) http://martinfowler.com/articles/nonDeterminism.html#Time Rollercoaster by Eric; flickr.com/photos/eric-omba/481762682; CC 2.0
  • 50. Problem: Libraries • Support libraries • Third party libraries • Implementation not empty, Run real code on tests Delivery by Bill; flickr.com/photos/34639780@N07/16480925469; CC 2.0
  • 51. Problem: Libraries Example: • Fragment:onStart is empty • SupportFragment:onStart actually does things Delivery by Bill; flickr.com/photos/34639780@N07/16480925469; CC 2.0
  • 52. Problem: Libraries • Needs more mocking • Might need Reflection work • Tricky on constructors i.e. custom views extends „empty“ android views Delivery by Bill; flickr.com/photos/34639780@N07/16480925469; CC 2.0
  • 53. Libraries (Reflection needed) CredentialsApi realApi = Auth.CredentialsApi; CredentialsApi apiMock = mock(CredentialsApi.class); SuperReflect.on(Auth.class).set("CredentialsApi", apiMock); ... tested.onConnected(mockBundle()); verify(apiMock).request( any(GoogleApiClient.class), any(CredentialRequest.class)); @After public void tearDown() { SuperReflect.on(Auth.class).set("CredentialsApi", realApi); }
  • 54. Write it nicer • mockView() instead of mock(View.class) ... • mockEditText(„test“)that implements Editable • mockFragmentTransaction() that returns self while building • mockRecyclerView() that remembers adapter https://github.com/dpreussler/mockitoid rainbow revisited by Bill Rosgen; flickr.com/photos/wrosgen/4706169184; CC 2.0
  • 55. Write it nicer • anyActivity() instead of any(Activity.class) • anyContext()... • anyView()... https://github.com/dpreussler/mockitoid rainbow revisited by Bill Rosgen; flickr.com/photos/wrosgen/4706169184; CC 2.0
  • 56. Gradually stop your addiction Subscription: Unmock Decide in gradle which classes you still need from Robolectric https://github.com/bjoernQ/unmock-plugin
  • 57. Any reasons to stick to Robolectric? “I need to test lots of UI” Test with mocks! “My tests are testing a complete flow” Your tests are too big “My tests depend on resources” Integration test? Move to Espresso?
  • 58. Any reasons to stick to Robolectric? “I want to test my SqlLiteOpenhelper with a real database?” Wrap SqlLiteopenHelper! Assert Query Strings (Use a java version of SQLlite if you real queries) No reason! And often smell for bad code design! Fix the code not the test!
  • 59. Groupon is Mobile One of worlds most popular apps > 50 Mio android downloads Unit testing by developers > 2000 unit test for Consumer app > 3000 unit tests for Merchant app Automation by QA engineers RoboRemote for Consumer app Appium for Merchant app