Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BABBQ5 - Automated Testing for Modern Android Applications

Andy Dyer
October 17, 2014

BABBQ5 - Automated Testing for Modern Android Applications

How to use dependency injection, mocking, and a test runner to automate UI & unit testing. Sample app source on GitHub: https://github.com/abdyer/android-test-demo

Andy Dyer

October 17, 2014
Tweet

More Decks by Andy Dyer

Other Decks in Programming

Transcript

  1. AUTOMATED TESTING FOR
    Modern ANDROID
    APPLICATIONS

    View full-size slide

  2. ANDY DYER
    +AndrewDyer || @dammitandy

    View full-size slide

  3. MUSIC LIBRARY

    View full-size slide

  4. WRIST PRESENTER

    View full-size slide

  5. RECORDS,
    COFFEE & BEER

    View full-size slide

  6. "Ich lerne Deutsch."

    View full-size slide

  7. MAKING ANDROID APPS TESTABLE

    View full-size slide

  8. DYNAMIC LANGUAGES
    "Tests shouldn't drive implementation."

    View full-size slide

  9. STATIC LANGUAGES
    "You know nothing."

    View full-size slide

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

    View full-size slide

  11. DEPENDENCY INJECTION

    View full-size slide

  12. 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

    View full-size slide

  13. 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;
    }
    }

    View full-size slide

  14. DAGGER
    A Java dependency injection library

    View full-size slide

  15. 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

    View full-size slide

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

    View full-size slide

  17. 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);
    }
    }

    View full-size slide

  18. 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();
    }
    }

    View full-size slide

  19. MOCKING & STUBBING

    View full-size slide

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

    View full-size slide

  21. MOCKITO
    A Java mocking library

    View full-size slide

  22. 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/

    View full-size slide

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

    View full-size slide

  24. UNIT & INTEGRATION TESTS

    View full-size slide

  25. "Tests or it didn't happen."

    View full-size slide

  26. ESPRESSO
    An Android UI test library

    View full-size slide

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

    View full-size slide

  28. 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))));
    }
    }

    View full-size slide

  29. 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

    View full-size slide

  30. HABEN SIE FRAGEN?

    View full-size slide

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

    View full-size slide