Slide 1

Slide 1 text

AUTOMATED TESTING FOR Modern ANDROID APPLICATIONS

Slide 2

Slide 2 text

ANDY DYER +AndrewDyer || @dammitandy

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

MUSIC LIBRARY

Slide 5

Slide 5 text

WRIST PRESENTER

Slide 6

Slide 6 text

RECORDS, COFFEE & BEER

Slide 7

Slide 7 text

"Ich lerne Deutsch."

Slide 8

Slide 8 text

MAKING ANDROID APPS TESTABLE

Slide 9

Slide 9 text

DYNAMIC LANGUAGES "Tests shouldn't drive implementation."

Slide 10

Slide 10 text

STATIC LANGUAGES "You know nothing."

Slide 11

Slide 11 text

MAKING ANDROID APPS TESTABLE ▸ Dependency injection ▸ Mocking & stubbing ▸ Unit & integration tests

Slide 12

Slide 12 text

DEPENDENCY INJECTION

Slide 13

Slide 13 text

DEPENDENCY INJECTION ▸ Decouples application components ▸ Classes receive dependencies, don’t have to know where to find them or how to create them ▸ Makes it easy to swap components for mocks in tests

Slide 14

Slide 14 text

BASIC DEPENDENCY INJECTION public class Beer { Water water; Barley barley; Hops hops; public Beer(Water water, Barley barley, Hops hops) { this.water = water; this.barley = barley; this.hops = hops; } }

Slide 15

Slide 15 text

DAGGER A Java dependency injection library

Slide 16

Slide 16 text

DAGGER ▸ Define dependencies at compile time to avoid reflection at runtime ▸ Compiler validates modules and injections ▸ Jake Wharton “Architecting Android Applications with Dagger" goo.gl/JIM7KI square.github.io/dagger

Slide 17

Slide 17 text

DAGGER MODULES @Module(injects = {MyActivity.class, MyFragment.class}) public class MyModule { @Provides @Singleton public MyService provideMyService() { return new MyService(); } }

Slide 18

Slide 18 text

DAGGER OBJECT GRAPH public class MyApplication extends Application { private dagger.ObjectGraph objectGraph; @Getter static MyApplication instance; @Override public void onCreate() { super.onCreate(); instance = this; objectGraph = dagger.ObjectGraph.create(new MyModule()); } public void inject(Object dependent) { objectGraph.inject(dependent); } }

Slide 19

Slide 19 text

DAGGER DEPENDENCY INJECTION public class MyFragment extends Fragment { @Inject MyService service; @Override public void onViewCreated(View view, Bundle savedInstanceState) { MyApplication.getInstance().inject(this); service.getMyData(); } }

Slide 20

Slide 20 text

MOCKING & STUBBING

Slide 21

Slide 21 text

MOCKING & STUBBING ▸ Substitute runtime implementation for something that can be predictably tested in isolation ▸ Verify behavior

Slide 22

Slide 22 text

MOCKITO A Java mocking library

Slide 23

Slide 23 text

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/

Slide 24

Slide 24 text

USING MOCKITO MyClass mocked = mock(MyClass.class); // code to inject mock & load activity/fragment // ... verify(mocked).getMyData(anyInt(), anyString());

Slide 25

Slide 25 text

UNIT & INTEGRATION TESTS

Slide 26

Slide 26 text

"Tests or it didn't happen."

Slide 27

Slide 27 text

ESPRESSO An Android UI test library

Slide 28

Slide 28 text

ESPRESSO ▸ Handles activity creation & state sync ▸ Simple, concise API ▸ Really fast! code.google.com/p/android-test-kit

Slide 29

Slide 29 text

USING ESPRESSO public class MyActivityTest extends ActivityInstrumentationTestCase2 { 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)))); } }

Slide 30

Slide 30 text

SAMPLE APPLICATION OVERVIEW ▸ Retrofit API with sample requests ▸ Dagger module ▸ Lombok & Android Studio plugin ▸ Login activity ▸ Activity with list fragment to make API request and display data

Slide 31

Slide 31 text

HABEN SIE FRAGEN?

Slide 32

Slide 32 text

CODE & SLIDES github.com/abdyer/android-test-demo