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

Unit Testing & Android

Unit Testing & Android

Lecture on Android unit testing and instrumentation testing, mDevCamp 2015. Overview of available libraries and frameworks, and their capabilities and drawbacks.

Tomáš Kypta

June 27, 2015
Tweet

More Decks by Tomáš Kypta

Other Decks in Programming

Transcript

  1. Legacy instrumentation tests • JUnit3 • Tests extend from TestCase

    • AndroidTestCase • ActivityInstrumentationTestCase2 • ServiceTestCase • …
  2. Testing Support Library • AndroidJUnitRunner • JUnit4 compatible android {

    defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } } androidTestCompile 'com.android.support.test:runner:0.3'
 androidTestCompile 'com.android.support.test:rules:0.3'
  3. Testing Support Library • Test filtering • @RequiresDevice - run

    on physical device, no emulator • @SdkSupress - don’t run on lower Android API level
  4. Test Sizes Feature Small Medium Large Network access No localhost

    only Yes Database No Yes Yes File system access No Yes Yes Use external systems No Discouraged Yes Multiple threads No Yes Yes Sleep statements No Yes Yes System properties No Yes Yes Time limit (seconds) 60 300 900+
  5. Potential problems • Manifest merger • problems when testing libraries

    • aar dependency using manifest placeholders • e.g. ${applicationId}, ${localApplicationId} android { defaultConfig { manifestPlaceholders = [localApplicationId:”com.example.mylib”] } }
  6. Problems • It affects the device! • Wiping contacts will

    wipe contacts! • You can’t prepare all test preconditions • e.g. you can’t dynamically change permissions
  7. Problems Test failed to run to completion. Reason: 'Instrumentation run

    failed due to 'java.lang.IllegalStateException''. Check device logcat for details
  8. • framework for functional UI tests • part of Android

    Testing Support Library androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
  9. @Test public void sayHello(){ onView(withId(R.id.editText)) .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); onView(withText("Say hello!”)) .perform(click());

    String expectedText = "Hello, " + STRING_TO_BE_TYPED + "!"; onView(withId(R.id.textView)) .check(matches(withText(expectedText))); }
  10. Problems • testing on device is not isolated • device

    state affects the result • e.g. screen on/off might affect test result onView(withId(R.id.my_view)) .check(matches(isDisplayed()));
  11. Grade and Android Studio support • natively supported since Gradle

    plugin 1.1.0 • big problems in AS in previous versions • has issues • switching between unit & instrumentation tests • disabled type is not indexed
  12. • the essential piece • alone can be used only

    for pure Java • don’t use on Android APIs!
  13. Method ... not mocked. android {
 testOptions {
 unitTests.returnDefaultValues =

    true
 }
 } • Helps rarely • returns 0, false, null, …
  14. • mocking framework • easy to use • compatible with

    Android unit testing testCompile ‘org.mockito:mockito-core:1.10.19'
  15. • can be used in instrumentation tests • needs dexmaker

    androidTestCompile ‘org.mockito:mockito-core:1.10.19' androidTestCompile "com.google.dexmaker:dexmaker:1.2" androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
  16. • Mockito.spy() • wrapping a real object • Mockito.verify() •

    verify that special condition are met • e.g. method called, called twice, …
  17. • at first, might be difficult to use • the

    ultimate mock of Android APIs • allows custom shadows • @RunWith(RobolectricTestRunner.class)
  18. • Robolectric class splits into • Robolectric • RuntimeEnvironment •

    Shadows • ShadowApplication • ShadowLooper 3.0-rc3
  19. Potential problems • difficult to search for solutions • long

    history of bigger changes • many obsolete posts
  20. Potential problems • difficulties running on command line and in

    AS • different paths • difficulty working with resources • RobolectricGradleTestRunner • doesn’t work in AS
  21. Code Coverage • unit tests • JaCoCo • instrumentation tests

    • EMMA • obsolete • Google is supposedly working on JaCoCo support
  22. JaCoCo • enabled by default for unit tests • generates

    binary report in build/jacoco • build/jacoco/testDebugUnitTest.exec • gradle test
  23. Code Coverage • don’t use it • generates coverage-instrumented-classes •

    for instrumentation tests • coverage for instrumentation tests is not ready buildTypes {
 debug {
 testCoverageEnabled true
 } }
  24. Good tests • run in any order • run in

    isolation • run consistently • run fast • are orthogonal
  25. Rules of thumb • prefer pure Java • abstract away

    from Android APIs • separate business logic and UI • don’t write business logic into activities and fragments • try avoid static methods • use dependency injection
  26. References • code coverage • JaCoCo • Eclipse Public License

    v1.0 • http://www.eclemma.org/jacoco/trunk/index.html • https://github.com/jacoco/jacoco • EMMA • Common Public License v1.0 • http://emma.sourceforge.net/