Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
MCE2015 - Automated Testing for Modern Android ...
Search
Andy Dyer
February 06, 2015
Programming
1.5k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
MCE2015 - Automated Testing for Modern Android Applications
Andy Dyer
February 06, 2015
More Decks by Andy Dyer
See All by Andy Dyer
AppCraft: Faster Than a Speeding Release Train
abdyer
1
380
Multiple Developers, One App: How to Not Break Everything
abdyer
0
390
Things That Suck About Android Development
abdyer
0
630
Building an Android Wear app
abdyer
0
110
BABBQ5 - Automated Testing for Modern Android Applications
abdyer
14
3.8k
Other Decks in Programming
See All in Programming
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
170
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
320
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
カツオ、ご期待ください
suneo3476
0
180
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
130
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
2
410
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
170
ActionController meets Protocol Buffers
sorah
0
430
phperだってパンチカードでコーディングしたい
o0h
PRO
0
320
最近”作らせてる” ローカルAIアプリの話
akit37
0
460
sbt 2.0: takeoff
eed3si9n
0
150
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
490
Featured
See All Featured
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
Facilitating Awesome Meetings
lara
57
7.2k
The Pragmatic Product Professional
lauravandoore
37
7.5k
Designing for humans not robots
tammielis
254
26k
Unsuck your backbone
ammeep
672
58k
Everyday Curiosity
cassininazir
0
350
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
450
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
360
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
Raft: Consensus for Rubyists
vanstee
142
7.8k
Transcript
Automated Testing for Modern Android Applications
Andy Dyer +AndrewDyer @dammitandy
None
Making Android apps testable
Dynamic languages Tests shouldn't drive implementation.
Static languages You know nothing.
Making Android apps testable 1. Dependency injection 2. Mocking &
stubbing 3. Unit & integration tests
Dependency injection
Dependency injection • Classes receive dependencies, don’t have to know
where to find them or how to create them • Swap components for mocks in tests • Use different components for different build flavors, etc.
Basic dependency injection public class Beer implements Reinheitsgebot { Water
water; Barley barley; Hops hops; public Beer(Water water, Barley barley, Hops hops) { this.water = water; this.barley = barley; this.hops = hops; } }
Dagger A Java dependency injection library
Dagger • Defining dependencies at compile time avoids reflection at
runtime • Compiler validates components, modules, and injections • Dagger 2 is currently in alpha, but already being used by Google in production apps google.github.io/dagger/
Dagger Modules @Module public class MyModule { @Provides @Singleton public
MyService provideMyService() { return new MyService(); } }
Dagger Components @Component(modules = MyModule.class) public interface Graph { void
inject(Activity activity); void inject(Fragment fragment); public final static class Initializer { public static Graph init(boolean mockMode) { return Dagger_Graph.builder().build(); } } }
Dagger Object Graph public class MyApplication extends Application { @Getter
static DemoApplication instance; @Getter Graph graph; @Override public void onCreate() { super.onCreate(); instance = this; graph = Graph.Initializer.init(false); } public void setMockMode(boolean useMock) { graph = Graph.Initializer.init(useMock); } }
Dagger dependency injection public class MyFragment extends Fragment { @Inject
MyService service; @Override public void onViewCreated(View view, Bundle savedInstanceState) { MyApplication.getInstance().getGraph().inject(this); service.getMyData(); } }
Learning more about Dagger • Jake Wharton - Dependency Injection
with Dagger 2 parleys.com/play/5471cdd1e4b065ebcfa1d557 • Gregory Kick - Dagger 2: A New Type of Dependency Injection youtube.com/watch?v=oK_XtfXPkqw
Mocking & Stubbing
Mocking & Stubbing • Substitute runtime implementation for something that
can be predictably tested in isolation • Verify behavior
A Java mocking library
Mockito • Mock/stub dependencies and function return values • Inject
mocks to validate behavior in tests • Use included Hamcrest matchers for clear, readable tests code.google.com/p/mockito/
Using Mockito // create mock MyClass mocked = mock(MyClass.class); //
specify behavior when(mocked.doSomething()).thenReturn(somethingElse); // verify method calls verify(mocked).getMyData(anyInt(), anyString());
Using Mockito // capture arguments ArgumentCaptor<Callback> captor = ArgumentCaptor.forClass(Callback.class); verify(authenticationService).login(anyString(),
anyString(), captor.capture()); // simulate error conditions, etc. captor.getValue().failure(RetrofitError.unexpectedError( "Invalid password", new Exception()));
Unit & Integration Tests
Tests or it didn't happen
Unit testing public class BeerTest extends InstrumentationTestCase { @Inject Beer
beer; @Override protected void setUp() throws Exception { MyApplication.getInstance().getGraph().inject(this); } public void testBeerIsGood() { assertTrue(beer.isGood()); } }
An Android UI testing library
Espresso • Handles activity creation & state sync • Simple,
concise API • Really fast! code.google.com/p/android-test-kit*
UI testing with Espresso public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity> {
public MyActivityTest() { super(MyActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); getActivity(); // trigger activity launch } public void testInvalidEmailShowsError() { onView(withId(R.id.email)).perform(typeText("abc"), closeSoftKeyboard()); onView(withId(R.id.email_sign_in_button)).perform(click()); onView(withId(R.id.email)).check(matches(withError( getActivity().getString(R.string.error_invalid_email)))); } }
Sample application • Dagger object graph • Retrofit API with
sample request • Lombok & Android Studio plugin • Login activity • Activity with fragment to make API request and display data
Testing the login activity • Simulate data entry and taps
to validate UI functionality • Simulate an error without making a network request
Testing the main activity • Verify the RecyclerView contains data
• Simulate taps to validate the appropriate URLs are loaded in a WebView
Testing the API • Use mock API response loaded from
text file to validate JSON parsing
Demo
Known issues • Some tests may fail on older devices/emulators
such as those running < API 18. Hopefully this will be fixed soon by an update to the test support library.
Additional resources • Bryan Stern/Circle Engineering - Instrumentation Testing with
Dagger, Mockito, and Espresso engineering.circle.com/instrumentation-testing-with-dagger- mockito-and-espresso
Conclusion Using dependency injection, mocking, and automated testing tools helps
us build better apps. Working together as a community, we can make testing even easier.
Questions?
Slides speakerdeck.com/abdyer/mce2015-automated-testing-for- modern-android-applications Code github.com/abdyer/android-test-demo/releases/tag/ mceconf-2015 +AndrewDyer @dammitandy