SlideShare a Scribd company logo
Unit Testing Experience on Android
Android apps are difficult to test
Types of Android tests
Types of Android tests
Instrumentation
tests
Local unit
tests
Android test code
• project sources
• ${module}/src/main/java
• instrumentation tests
• ${module}/src/androidTest/java
• unit tests
• ${module}/src/test/java
• full Gradle and Android Studio support
• the essential piece of both instrumentation and unit tests
• alone can be used only for pure Java
• doesn’t provide any mocks or Android APIs
Instrumentation Tests
Instrumentation Tests
• running on physical device or emulator
• gradle connectedAndroidTest
• ${module}/build/reports/androidTests/connected/
index.html
Instrumentation Tests
Legacy instrumentation tests
or
Testing Support Library
Legacy Instrumentation Tests
• JUnit3
• Tests extend from TestCase
• AndroidTestCase
• ActivityInstrumentationTestCase2
• ServiceTestCase
• …
deprecated
since API
level 24
Testing Support Library
• JUnit4 compatible
• AndroidJUnitRunner
android {
defaultConfig {
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
}
dependencies {
androidTestCompile 'com.android.support.test:runner:0.5'
}
Testing Support Library
• JUnit test rules
• AndroidTestRule
• ServiceTestRule
• DisableOnAndroidDebug
• LogLogcatRule
• …
androidTestCompile 'com.android.support.test:rules:0.5'
• framework for functional UI tests
• part of Android Testing Support Library
androidTestCompile
'com.android.support.test.espresso:espresso-core:2.2.2'
@Test
public void sayHello() {
onView(withId(R.id.edit_text))
.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)));
}
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()));
Some annoyances
android.support.test.espresso.NoActivityResumedException:
No activities in stage RESUMED.
Did you forget to launch the activity. (test.getActivity() or similar)?
Instrumentation tests
are
kinda
SLOOOOOW
Unit Tests
Unit Tests
• run on JVM
• mockable android.jar
• gradle test
• ${module}/build/reports/tests/${variant}/index.html
...
• Helps rarely
• returns 0, false, null, …
Method ... not mocked.
android {

testOptions {

unitTests.returnDefaultValues = true
}

}
• mocking framework
• easy to use
• compatible with Android unit testing
testCompile 'org.mockito:mockito-core:2.2.11'
• can be used also in instrumentation tests
• needs dexmaker
androidTestCompile 'org.mockito:mockito-core:2.2.11'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
@RunWith(JUnit4.class)
public class ContextManagerTest {
@Mock Context mAppContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testWithContext() {
…
}
}
@RunWith(MockitoJUnitRunner.class)
public class ContextManagerTest {
@Mock Context mAppContext;
@Test
public void testWithContext() {
…
}
}
@RunWith(JUnit4.class)
public class ContextManagerTest {
@Test
public void testWithContext() {
Context appContext = mock(Context.class);
Mockito.when(appContext.getPackageName())
.thenReturn(“com.example.app”);
…
}
}
• Mockito.spy()
• wrapping a real object
• Mockito.verify()
• verify that special condition are met
• e.g. method called, method called twice, …
Limitations
• final classes
• opt-in incubating support in Mockito 2
• anonymous classes
• primitive types
• static methods
• functional testing framework
• runs on JVM
• at first, might be difficult to use
• the ultimate mock of Android APIs
• provides mocks of system managers
• allows custom shadows
• possible to use for UI testing
• better to use for business logic
@RunWith(RobolectricTestRunner.class)
public class MyTest {
…
}
• Robolectric
• RuntimeEnvironment
• Shadows
• ShadowApplication
• ShadowLooper
Potential problems
• difficult to search for solutions
• long history of bigger API changes
• many obsolete posts
• Can mock static methods
• Can be used together with Mockito
@RunWith(PowerMockRunner.class)
@PrepareForTest(Static.class);
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.staticMethod())
.thenReturn(value);
PowerMockito.verifyStatic(Static.class);
• “matchers on steroids”
• offers more complex checks
assertThat(myClass, isInstanceOf(MainActivity.class));
assertThat(myManager.getValue(), isEqualTo(someValue));
assertThat(value, isIn(listOfValues));
assertThat(value, not(isIn(listOfValues)));
• cross-platform BDD framework
• human-like test definitions
testCompile ‘junit:junit:4.12'
testCompile ‘info.cukes:cucumber-java:1.2.5'
testCompile 'info.cukes:cucumber-junit:1.2.5'
• describe the desired behaviour
Feature: CoffeeMaker



Scenario: a few coffees

Given I previously had 3 coffees

When I add one coffee

Then I had 4 coffees
• create the
mapping
public class CoffeeMakerDefs {

CoffeeMaker mCoffeeMaker = new CoffeeMaker();









}
• create the
mapping
public class CoffeeMakerDefs {

CoffeeMaker mCoffeeMaker = new CoffeeMaker();



@Given("^I previously had (d+) coffees$")

public void hadCoffeesPreviously(int coffees) {

mCoffeeMaker.setCoffeeCount(coffees);

}





}
• create the
mapping
public class CoffeeMakerDefs {

CoffeeMaker mCoffeeMaker = new CoffeeMaker();



@Given("^I previously had (d+) coffees$")

public void hadCoffeesPreviously(int coffees) {

mCoffeeMaker.setCoffeeCount(coffees);

}



@When("^I add one coffee$")

public void addCoffee() {

mCoffeeMaker.addCoffee();

}





}
• create the
mapping
public class CoffeeMakerDefs {

CoffeeMaker mCoffeeMaker = new CoffeeMaker();



@Given("^I previously had (d+) coffees$")

public void hadCoffeesPreviously(int coffees) {

mCoffeeMaker.setCoffeeCount(coffees);

}



@When("^I add one coffee$")

public void addCoffee() {

mCoffeeMaker.addCoffee();

}



@Then("^I had (d+) coffees$")

public void hadCoffees(int coffees) {

Assert.assertEquals(coffees, mCoffeeMaker.getCoffeeCount());

}

}
• place definition and mapping at the same paths!
• ${module}/src/test/java/com/example/MyMapping.java
• ${module}/src/test/resources/com/example/
MyDefinition.feature
@RunWith(Cucumber.class)

public class RunCucumberTest {

}
Code Coverage
Code Coverage
• instrumentation tests
• JaCoCo
• EMMA
• obsolete
• unit tests
• JaCoCo
Instrumentation Tests & Code Coverage
• has to be explicitly enabled
• gradle createDebugCoverageReport
• ${module}/build/reports/coverage/debug/index.html
• ${module}/build/outputs/code-coverage/connected/$
{deviceName}-coverage.ec
• doesn’t work on some devices!!!
buildTypes {

debug {

testCoverageEnabled true

}
}
JaCoCo
JaCoCo
• enabled by default for unit tests
• gradle test
• generates binary report in build/jacoco
• ${module}/build/jacoco/testDebugUnitTest.exec
• it’s necessary to create a JacocoReport task to obtain a readable
report
Good tests
Good tests
• run in any order
• run in isolation
• run consistently
• run fast
• are orthogonal
How to write testable apps?
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
• MVP, MVVM is a way to go
• try avoid static and final
• use dependency injection
Questions?

More Related Content

What's hot

An introduction to maven gradle and sbt
An introduction to maven gradle and sbtAn introduction to maven gradle and sbt
An introduction to maven gradle and sbt
Fabio Fumarola
 
SBT Crash Course
SBT Crash CourseSBT Crash Course
SBT Crash Course
Michal Bigos
 
iOS UI Testing in Xcode
iOS UI Testing in XcodeiOS UI Testing in Xcode
iOS UI Testing in Xcode
Jz Chang
 
Android L01 - Warm Up
Android L01 - Warm UpAndroid L01 - Warm Up
Android L01 - Warm Up
Mohammad Shaker
 
Apache Ant
Apache AntApache Ant
Apache Ant
Ali Bahu
 
Java Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissJava Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to Miss
Andres Almiray
 
ScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency InjectionScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency Injection
7mind
 
Test like a pro with Ember.js
Test like a pro with Ember.jsTest like a pro with Ember.js
Test like a pro with Ember.js
Mike North
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
Andres Almiray
 
Scala, Functional Programming and Team Productivity
Scala, Functional Programming and Team ProductivityScala, Functional Programming and Team Productivity
Scala, Functional Programming and Team Productivity
7mind
 
Android classes in mumbai
Android classes in mumbaiAndroid classes in mumbai
Android classes in mumbai
Vibrant Technologies & Computers
 
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
Danny Preussler
 
A fresh look at Java Enterprise Application testing with Arquillian
A fresh look at Java Enterprise Application testing with ArquillianA fresh look at Java Enterprise Application testing with Arquillian
A fresh look at Java Enterprise Application testing with Arquillian
Vineet Reynolds
 
Hyper-pragmatic Pure FP testing with distage-testkit
Hyper-pragmatic Pure FP testing with distage-testkitHyper-pragmatic Pure FP testing with distage-testkit
Hyper-pragmatic Pure FP testing with distage-testkit
7mind
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
Andres Almiray
 
Arquillian in a nutshell
Arquillian in a nutshellArquillian in a nutshell
Arquillian in a nutshell
Brockhaus Group
 
Writing Custom Puppet Types and Providers to Manage Web-Based Applications
Writing Custom Puppet Types and Providers to Manage Web-Based ApplicationsWriting Custom Puppet Types and Providers to Manage Web-Based Applications
Writing Custom Puppet Types and Providers to Manage Web-Based Applications
Tim Cinel
 
Ember testing internals with ember cli
Ember testing internals with ember cliEmber testing internals with ember cli
Ember testing internals with ember cli
Cory Forsyth
 
Droidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineDroidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offline
Javier de Pedro López
 
Grails plugin development
Grails plugin developmentGrails plugin development
Grails plugin development
Mohd Farid
 

What's hot (20)

An introduction to maven gradle and sbt
An introduction to maven gradle and sbtAn introduction to maven gradle and sbt
An introduction to maven gradle and sbt
 
SBT Crash Course
SBT Crash CourseSBT Crash Course
SBT Crash Course
 
iOS UI Testing in Xcode
iOS UI Testing in XcodeiOS UI Testing in Xcode
iOS UI Testing in Xcode
 
Android L01 - Warm Up
Android L01 - Warm UpAndroid L01 - Warm Up
Android L01 - Warm Up
 
Apache Ant
Apache AntApache Ant
Apache Ant
 
Java Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissJava Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to Miss
 
ScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency InjectionScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency Injection
 
Test like a pro with Ember.js
Test like a pro with Ember.jsTest like a pro with Ember.js
Test like a pro with Ember.js
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
 
Scala, Functional Programming and Team Productivity
Scala, Functional Programming and Team ProductivityScala, Functional Programming and Team Productivity
Scala, Functional Programming and Team Productivity
 
Android classes in mumbai
Android classes in mumbaiAndroid classes in mumbai
Android classes in mumbai
 
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
 
A fresh look at Java Enterprise Application testing with Arquillian
A fresh look at Java Enterprise Application testing with ArquillianA fresh look at Java Enterprise Application testing with Arquillian
A fresh look at Java Enterprise Application testing with Arquillian
 
Hyper-pragmatic Pure FP testing with distage-testkit
Hyper-pragmatic Pure FP testing with distage-testkitHyper-pragmatic Pure FP testing with distage-testkit
Hyper-pragmatic Pure FP testing with distage-testkit
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
 
Arquillian in a nutshell
Arquillian in a nutshellArquillian in a nutshell
Arquillian in a nutshell
 
Writing Custom Puppet Types and Providers to Manage Web-Based Applications
Writing Custom Puppet Types and Providers to Manage Web-Based ApplicationsWriting Custom Puppet Types and Providers to Manage Web-Based Applications
Writing Custom Puppet Types and Providers to Manage Web-Based Applications
 
Ember testing internals with ember cli
Ember testing internals with ember cliEmber testing internals with ember cli
Ember testing internals with ember cli
 
Droidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineDroidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offline
 
Grails plugin development
Grails plugin developmentGrails plugin development
Grails plugin development
 

Viewers also liked

Writing testable Android apps
Writing testable Android appsWriting testable Android apps
Writing testable Android apps
Tomáš Kypta
 
Android Develpment vol. 2, MFF UK, 2015
Android Develpment vol. 2, MFF UK, 2015Android Develpment vol. 2, MFF UK, 2015
Android Develpment vol. 2, MFF UK, 2015
Tomáš Kypta
 
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
Tomáš Kypta
 
Android Develpment vol. 3, MFF UK, 2015
Android Develpment vol. 3, MFF UK, 2015Android Develpment vol. 3, MFF UK, 2015
Android Develpment vol. 3, MFF UK, 2015
Tomáš Kypta
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
Tomáš Kypta
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
Tomáš Kypta
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
Tomáš Kypta
 

Viewers also liked (7)

Writing testable Android apps
Writing testable Android appsWriting testable Android apps
Writing testable Android apps
 
Android Develpment vol. 2, MFF UK, 2015
Android Develpment vol. 2, MFF UK, 2015Android Develpment vol. 2, MFF UK, 2015
Android Develpment vol. 2, MFF UK, 2015
 
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
 
Android Develpment vol. 3, MFF UK, 2015
Android Develpment vol. 3, MFF UK, 2015Android Develpment vol. 3, MFF UK, 2015
Android Develpment vol. 3, MFF UK, 2015
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 

Similar to Guide to the jungle of testing frameworks

Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
Android Meetup Slovenija #3 - Testing with Robolectric by Ivan KustAndroid Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
Infinum
 
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum Android Talks #17 - Testing your Android applications by Ivan KustInfinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
Hendrik Ebbers
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
Sunghyouk Bae
 
Android Unit Test
Android Unit TestAndroid Unit Test
Android Unit Test
Phuoc Bui
 
Unit Testing on Android - Droidcon Berlin 2015
Unit Testing on Android - Droidcon Berlin 2015Unit Testing on Android - Droidcon Berlin 2015
Unit Testing on Android - Droidcon Berlin 2015
Buşra Deniz, CSM
 
Renaissance of JUnit - Introduction to JUnit 5
Renaissance of JUnit - Introduction to JUnit 5Renaissance of JUnit - Introduction to JUnit 5
Renaissance of JUnit - Introduction to JUnit 5
Jimmy Lu
 
Gradle
GradleGradle
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 
Apache DeltaSpike
Apache DeltaSpikeApache DeltaSpike
Apache DeltaSpike
os890
 
Unit testing and Android
Unit testing and AndroidUnit testing and Android
Unit testing and Android
Tomáš Kypta
 
Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2
Kirill Rozov
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
rajdeep
 
Testing Your Application On Google App Engine
Testing Your Application On Google App EngineTesting Your Application On Google App Engine
Testing Your Application On Google App Engine
IndicThreads
 
Testing your application on Google App Engine
Testing your application on Google App EngineTesting your application on Google App Engine
Testing your application on Google App Engine
Inphina Technologies
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Nicolas HAAN
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
Steven Smith
 
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
FalafelSoftware
 
Junit_.pptx
Junit_.pptxJunit_.pptx
Junit_.pptx
Suman Sourav
 
谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability
drewz lin
 

Similar to Guide to the jungle of testing frameworks (20)

Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
Android Meetup Slovenija #3 - Testing with Robolectric by Ivan KustAndroid Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
 
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum Android Talks #17 - Testing your Android applications by Ivan KustInfinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
 
Android Unit Test
Android Unit TestAndroid Unit Test
Android Unit Test
 
Unit Testing on Android - Droidcon Berlin 2015
Unit Testing on Android - Droidcon Berlin 2015Unit Testing on Android - Droidcon Berlin 2015
Unit Testing on Android - Droidcon Berlin 2015
 
Renaissance of JUnit - Introduction to JUnit 5
Renaissance of JUnit - Introduction to JUnit 5Renaissance of JUnit - Introduction to JUnit 5
Renaissance of JUnit - Introduction to JUnit 5
 
Gradle
GradleGradle
Gradle
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Apache DeltaSpike
Apache DeltaSpikeApache DeltaSpike
Apache DeltaSpike
 
Unit testing and Android
Unit testing and AndroidUnit testing and Android
Unit testing and Android
 
Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
 
Testing Your Application On Google App Engine
Testing Your Application On Google App EngineTesting Your Application On Google App Engine
Testing Your Application On Google App Engine
 
Testing your application on Google App Engine
Testing your application on Google App EngineTesting your application on Google App Engine
Testing your application on Google App Engine
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
 
Junit_.pptx
Junit_.pptxJunit_.pptx
Junit_.pptx
 
谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability
 

More from Tomáš Kypta

Modern Android app library stack
Modern Android app library stackModern Android app library stack
Modern Android app library stack
Tomáš Kypta
 
ProGuard
ProGuardProGuard
ProGuard
Tomáš Kypta
 
Android Development for Phone and Tablet
Android Development for Phone and TabletAndroid Development for Phone and Tablet
Android Development for Phone and Tablet
Tomáš Kypta
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
Tomáš Kypta
 
Android development - the basics, MFF UK, 2014
Android development - the basics, MFF UK, 2014Android development - the basics, MFF UK, 2014
Android development - the basics, MFF UK, 2014
Tomáš Kypta
 
Android Libraries
Android LibrariesAndroid Libraries
Android Libraries
Tomáš Kypta
 
Android Development 201
Android Development 201Android Development 201
Android Development 201
Tomáš Kypta
 
Android development - the basics, MFF UK, 2013
Android development - the basics, MFF UK, 2013Android development - the basics, MFF UK, 2013
Android development - the basics, MFF UK, 2013
Tomáš Kypta
 
Užitečné Android knihovny pro vývoj a testování
Užitečné Android knihovny pro vývoj a testováníUžitečné Android knihovny pro vývoj a testování
Užitečné Android knihovny pro vývoj a testování
Tomáš Kypta
 
Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013
Tomáš Kypta
 
Stylování ActionBaru
Stylování ActionBaruStylování ActionBaru
Stylování ActionBaru
Tomáš Kypta
 
Android development - the basics, MFF UK, 2012
Android development - the basics, MFF UK, 2012Android development - the basics, MFF UK, 2012
Android development - the basics, MFF UK, 2012
Tomáš Kypta
 
Android development - the basics, FI MUNI, 2012
Android development - the basics, FI MUNI, 2012Android development - the basics, FI MUNI, 2012
Android development - the basics, FI MUNI, 2012
Tomáš Kypta
 

More from Tomáš Kypta (13)

Modern Android app library stack
Modern Android app library stackModern Android app library stack
Modern Android app library stack
 
ProGuard
ProGuardProGuard
ProGuard
 
Android Development for Phone and Tablet
Android Development for Phone and TabletAndroid Development for Phone and Tablet
Android Development for Phone and Tablet
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Android development - the basics, MFF UK, 2014
Android development - the basics, MFF UK, 2014Android development - the basics, MFF UK, 2014
Android development - the basics, MFF UK, 2014
 
Android Libraries
Android LibrariesAndroid Libraries
Android Libraries
 
Android Development 201
Android Development 201Android Development 201
Android Development 201
 
Android development - the basics, MFF UK, 2013
Android development - the basics, MFF UK, 2013Android development - the basics, MFF UK, 2013
Android development - the basics, MFF UK, 2013
 
Užitečné Android knihovny pro vývoj a testování
Užitečné Android knihovny pro vývoj a testováníUžitečné Android knihovny pro vývoj a testování
Užitečné Android knihovny pro vývoj a testování
 
Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013
 
Stylování ActionBaru
Stylování ActionBaruStylování ActionBaru
Stylování ActionBaru
 
Android development - the basics, MFF UK, 2012
Android development - the basics, MFF UK, 2012Android development - the basics, MFF UK, 2012
Android development - the basics, MFF UK, 2012
 
Android development - the basics, FI MUNI, 2012
Android development - the basics, FI MUNI, 2012Android development - the basics, FI MUNI, 2012
Android development - the basics, FI MUNI, 2012
 

Recently uploaded

Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
LucaBarbaro3
 
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - HiikeSystem Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
Hiike
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
AstuteBusiness
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
Intelisync
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
Postman
 
AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
HarisZaheer8
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
Miro Wengner
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
Public CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptxPublic CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptx
marufrahmanstratejm
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Wask
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
Dinusha Kumarasiri
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 

Recently uploaded (20)

Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
 
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - HiikeSystem Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
 
AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
Public CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptxPublic CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptx
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 

Guide to the jungle of testing frameworks

  • 1.
  • 3.
  • 4. Android apps are difficult to test
  • 6. Types of Android tests Instrumentation tests Local unit tests
  • 7. Android test code • project sources • ${module}/src/main/java • instrumentation tests • ${module}/src/androidTest/java • unit tests • ${module}/src/test/java • full Gradle and Android Studio support
  • 8.
  • 9. • the essential piece of both instrumentation and unit tests • alone can be used only for pure Java • doesn’t provide any mocks or Android APIs
  • 11. Instrumentation Tests • running on physical device or emulator • gradle connectedAndroidTest • ${module}/build/reports/androidTests/connected/ index.html
  • 12.
  • 13. Instrumentation Tests Legacy instrumentation tests or Testing Support Library
  • 14. Legacy Instrumentation Tests • JUnit3 • Tests extend from TestCase • AndroidTestCase • ActivityInstrumentationTestCase2 • ServiceTestCase • … deprecated since API level 24
  • 15. Testing Support Library • JUnit4 compatible • AndroidJUnitRunner android { defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } } dependencies { androidTestCompile 'com.android.support.test:runner:0.5' }
  • 16. Testing Support Library • JUnit test rules • AndroidTestRule • ServiceTestRule • DisableOnAndroidDebug • LogLogcatRule • … androidTestCompile 'com.android.support.test:rules:0.5'
  • 17.
  • 18. • framework for functional UI tests • part of Android Testing Support Library androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
  • 19. @Test public void sayHello() { onView(withId(R.id.edit_text)) .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))); }
  • 20. 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()));
  • 21. Some annoyances android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?
  • 24. Unit Tests • run on JVM • mockable android.jar • gradle test • ${module}/build/reports/tests/${variant}/index.html
  • 25. ...
  • 26.
  • 27. • Helps rarely • returns 0, false, null, … Method ... not mocked. android {
 testOptions {
 unitTests.returnDefaultValues = true }
 }
  • 28.
  • 29. • mocking framework • easy to use • compatible with Android unit testing testCompile 'org.mockito:mockito-core:2.2.11'
  • 30. • can be used also in instrumentation tests • needs dexmaker androidTestCompile 'org.mockito:mockito-core:2.2.11' androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
  • 31. @RunWith(JUnit4.class) public class ContextManagerTest { @Mock Context mAppContext; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void testWithContext() { … } }
  • 32. @RunWith(MockitoJUnitRunner.class) public class ContextManagerTest { @Mock Context mAppContext; @Test public void testWithContext() { … } }
  • 33. @RunWith(JUnit4.class) public class ContextManagerTest { @Test public void testWithContext() { Context appContext = mock(Context.class); Mockito.when(appContext.getPackageName()) .thenReturn(“com.example.app”); … } }
  • 34. • Mockito.spy() • wrapping a real object • Mockito.verify() • verify that special condition are met • e.g. method called, method called twice, …
  • 35. Limitations • final classes • opt-in incubating support in Mockito 2 • anonymous classes • primitive types • static methods
  • 36.
  • 37. • functional testing framework • runs on JVM • at first, might be difficult to use • the ultimate mock of Android APIs • provides mocks of system managers • allows custom shadows
  • 38. • possible to use for UI testing • better to use for business logic @RunWith(RobolectricTestRunner.class) public class MyTest { … }
  • 39. • Robolectric • RuntimeEnvironment • Shadows • ShadowApplication • ShadowLooper
  • 40. Potential problems • difficult to search for solutions • long history of bigger API changes • many obsolete posts
  • 41.
  • 42. • Can mock static methods • Can be used together with Mockito
  • 44.
  • 45. • “matchers on steroids” • offers more complex checks assertThat(myClass, isInstanceOf(MainActivity.class)); assertThat(myManager.getValue(), isEqualTo(someValue)); assertThat(value, isIn(listOfValues)); assertThat(value, not(isIn(listOfValues)));
  • 46.
  • 47. • cross-platform BDD framework • human-like test definitions testCompile ‘junit:junit:4.12' testCompile ‘info.cukes:cucumber-java:1.2.5' testCompile 'info.cukes:cucumber-junit:1.2.5'
  • 48. • describe the desired behaviour Feature: CoffeeMaker
 
 Scenario: a few coffees
 Given I previously had 3 coffees
 When I add one coffee
 Then I had 4 coffees
  • 49. • create the mapping public class CoffeeMakerDefs {
 CoffeeMaker mCoffeeMaker = new CoffeeMaker();
 
 
 
 
 }
  • 50. • create the mapping public class CoffeeMakerDefs {
 CoffeeMaker mCoffeeMaker = new CoffeeMaker();
 
 @Given("^I previously had (d+) coffees$")
 public void hadCoffeesPreviously(int coffees) {
 mCoffeeMaker.setCoffeeCount(coffees);
 }
 
 
 }
  • 51. • create the mapping public class CoffeeMakerDefs {
 CoffeeMaker mCoffeeMaker = new CoffeeMaker();
 
 @Given("^I previously had (d+) coffees$")
 public void hadCoffeesPreviously(int coffees) {
 mCoffeeMaker.setCoffeeCount(coffees);
 }
 
 @When("^I add one coffee$")
 public void addCoffee() {
 mCoffeeMaker.addCoffee();
 }
 
 
 }
  • 52. • create the mapping public class CoffeeMakerDefs {
 CoffeeMaker mCoffeeMaker = new CoffeeMaker();
 
 @Given("^I previously had (d+) coffees$")
 public void hadCoffeesPreviously(int coffees) {
 mCoffeeMaker.setCoffeeCount(coffees);
 }
 
 @When("^I add one coffee$")
 public void addCoffee() {
 mCoffeeMaker.addCoffee();
 }
 
 @Then("^I had (d+) coffees$")
 public void hadCoffees(int coffees) {
 Assert.assertEquals(coffees, mCoffeeMaker.getCoffeeCount());
 }
 }
  • 53. • place definition and mapping at the same paths! • ${module}/src/test/java/com/example/MyMapping.java • ${module}/src/test/resources/com/example/ MyDefinition.feature @RunWith(Cucumber.class)
 public class RunCucumberTest {
 }
  • 55. Code Coverage • instrumentation tests • JaCoCo • EMMA • obsolete • unit tests • JaCoCo
  • 56. Instrumentation Tests & Code Coverage • has to be explicitly enabled • gradle createDebugCoverageReport • ${module}/build/reports/coverage/debug/index.html • ${module}/build/outputs/code-coverage/connected/$ {deviceName}-coverage.ec • doesn’t work on some devices!!! buildTypes {
 debug {
 testCoverageEnabled true
 } }
  • 58. JaCoCo • enabled by default for unit tests • gradle test • generates binary report in build/jacoco • ${module}/build/jacoco/testDebugUnitTest.exec • it’s necessary to create a JacocoReport task to obtain a readable report
  • 59.
  • 60.
  • 62. Good tests • run in any order • run in isolation • run consistently • run fast • are orthogonal
  • 63. How to write testable apps?
  • 64. 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 • MVP, MVVM is a way to go • try avoid static and final • use dependency injection