SlideShare a Scribd company logo
Guide to the jungle of testing frameworks
Unit Testing Experience on Android
Guide to the jungle of testing frameworks
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
Guide to the jungle of testing frameworks
• 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
Guide to the jungle of testing frameworks
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'
Guide to the jungle of testing frameworks
• 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
...
Guide to the jungle of testing frameworks
• Helps rarely
• returns 0, false, null, …
Method ... not mocked.
android {

testOptions {

unitTests.returnDefaultValues = true
}

}
Guide to the jungle of testing frameworks
• 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
Guide to the jungle of testing frameworks
• 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
Guide to the jungle of testing frameworks
• 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);
Guide to the jungle of testing frameworks
• “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)));
Guide to the jungle of testing frameworks
• 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
Guide to the jungle of testing frameworks
Guide to the jungle of testing frameworks
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 (20)

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

Viewers also liked (7)

PDF
Writing testable Android apps
Tomáš Kypta
 
PDF
Android Develpment vol. 2, MFF UK, 2015
Tomáš Kypta
 
PDF
Guide to the jungle of testing frameworks
Tomáš Kypta
 
PDF
Android Develpment vol. 3, MFF UK, 2015
Tomáš Kypta
 
PDF
Reactive programming on Android
Tomáš Kypta
 
PDF
Practical RxJava for Android
Tomáš Kypta
 
PDF
Practical RxJava for Android
Tomáš Kypta
 
Writing testable Android apps
Tomáš Kypta
 
Android Develpment vol. 2, MFF UK, 2015
Tomáš Kypta
 
Guide to the jungle of testing frameworks
Tomáš Kypta
 
Android Develpment vol. 3, MFF UK, 2015
Tomáš Kypta
 
Reactive programming on Android
Tomáš Kypta
 
Practical RxJava for Android
Tomáš Kypta
 
Practical RxJava for Android
Tomáš Kypta
 
Ad

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

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

More from Tomáš Kypta (13)

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

Recently uploaded (20)

PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PPTX
✨Unleashing Collaboration: Salesforce Channels & Community Power in Patna!✨
SanjeetMishra29
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Windsurf Meetup Ottawa 2025-07-12 - Planning Mode at Reliza.pdf
Pavel Shukhman
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Python basic programing language for automation
DanialHabibi2
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
✨Unleashing Collaboration: Salesforce Channels & Community Power in Patna!✨
SanjeetMishra29
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
July Patch Tuesday
Ivanti
 
Windsurf Meetup Ottawa 2025-07-12 - Planning Mode at Reliza.pdf
Pavel Shukhman
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Python basic programing language for automation
DanialHabibi2
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 

Guide to the jungle of testing frameworks

  • 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
  • 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
  • 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'
  • 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. ...
  • 27. • Helps rarely • returns 0, false, null, … Method ... not mocked. android {
 testOptions {
 unitTests.returnDefaultValues = true }
 }
  • 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
  • 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
  • 42. • Can mock static methods • Can be used together with Mockito
  • 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)));
  • 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
  • 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