SlideShare ist ein Scribd-Unternehmen logo
1 von 39
Downloaden Sie, um offline zu lesen
Testing with
Robolectric
IVAN KUŠT, ANDROID TEAM LEADER
ROBOLECTRIC
• http://robolectric.org/
• unit test framework
• tests run in JVM on your machine
CODE EXAMPLE
• https://github.com/infinum/Dagger-2-Example
01SETTING UP ROBOLECTRIC
ROBOLECTRIC SETUP
1. Add gradle dependencies
2. write test Application class
3. write test class
4. run tests
1. ADD DEPENDENCIES
• make sure “Unit tests” is selected as Test Artifact under
Build Variants
• add the robolectric dependency in your app build.gradle file:
// Robolectric

testCompile 'junit:junit:4.12'

testCompile 'org.hamcrest:hamcrest-library:1.3'

testCompile 'org.apache.maven:maven-ant-tasks:2.1.3' // fixes issue on linux/mac

testCompile('org.robolectric:robolectric:3.0')
2. WRITE TEST APPLICATION CLASS
• all unit test code goes into test flavour
• Test{applicationName}
• must extend your application class
• runs instead of application class in tests
• should inject test dependencies
3. WRITE TEST CLASS
• create new class in test flavor
• specify runner with @RunWith annotation
• add @Config annotation
• add test methods and annotate them with @Test
3.5 TEST CONFIGURATION
• constants property of @Config annotation is mandatory
• options (except constants) can be specified in a file instead:

/test/resources/robolectric.properties
• for other options check:

http://robolectric.org/configuring/
@RunWith(RobolectricGradleTestRunner.class)

@Config(constants = BuildConfig.class, sdk = 21)

public class DeckardActivityTest {



@Test

public void testSomething() throws Exception {

assertTrue(Robolectric.setupActivity(DeckardActivity.class) != null);

}

}
4. RUN TESTS
• from Android studio
• ./gradlew clean test
TEST REPORT
• will be generated in:

/app/build/reports/tests/{flavour}/index.html

• if tests faill, gradle will print out the location of the report in
console as well
LOGS
• to show Log.d() outputs add following in your @Before
method:



ShadowLog.stream = System.out;
01SYNCHRONOUS EXECUTORS
(A)SYNCHRONOUS EXECUTORS
• unit tests run in a single thread

• waiting for background threads complicates tests

• solution: Synchronous executors (for Retrofit)
SETUP
• setting executor on Retrofit:







• specify executor for networking and callbacks

• for tests: both synchronous
return new RestAdapter.Builder()

...

.setExecutors(new BackgroundExecutor(), new CallbackExecutor())

...

.build();
SYNCHRONOUS EXECUTOR?
• runs the queued runnable in the same thread

• simple as that:
public class SynchronousExecutor implements Executor {


@Override

public void execute(Runnable command) {

command.run();

}

}
01MOCK WEB SERVER
MOCK WEB SEVER
• part of OkHttp library by Square

• network responses must be mocked in unit tests
• speed
• consistency
MOCK WEB SERVER DEPENDENCIES
• add the MockWebServer dependency in your app
build.gradle file:




• MockWebServer depends on OkHttp library
• make sure that versions match
testCompile ‘com.squareup.okhttp:mockwebserver:2.4.0'
USING MOCKWEBSERVER
1. Instantiate MockWebServer
2. call start() method
3. get local server url by calling url(“/“)
4. inject local server url into networking module
5. enqueue responses using enqueue() method
INSTANTIATING MOCK WEB SERVER
• prepare and inject MockWebServer in @Before method
(called before every @Test method)
• stop MockWebServer in @After method (called after every
@Test method)
INSTANTIATING MOCK WEB SERVER
• another option:
• implement TestLifecycleApplication in Test application
class

• prepare and inject MockWebServer in

beforeTest(Method) method in Test application class

• stop MockWebServer in:

afterTest(Method) in Test application class
ENQUEUEING RESPONSES
• enqueue(), MockResponse object
• https://github.com/square/okhttp/blob/master/
mockwebserver/src/main/java/com/squareup/okhttp/
mockwebserver/MockResponse.java
mockWebServer.enqueue(

new MockResponse()

.setResponseCode(200)

.setBody(“Response body”)

);
WHAT ABOUT LARGE RESPONSES?
1. Store response body content to a file

2. put the file inside /test/resources/ directory

3. read the contents of the file in test:
public static String readFromFile(String filename) {

InputStream is = ResourceUtils.class.getClassLoader().getResourceAsStream(filename));

return convertStreamToString(is);

}
CHECKING REQUESTS
• mockWebServer.getRequestCount()

• mockWebServer.takeRequest()

• mockWebServer.takeRequest(long, TimeUnit)
EXAMPLE
@Test

public void nameOk() throws Exception {

PokemonTestApp.getMockWebServer().enqueue(

new MockResponse()

.setResponseCode(200)

.setBody(ResourceUtils.readFromFile("charizard.json"))

);



String resourceUri = "api/v1/pokemon/6/";

Pokemon pokemon = new Pokemon();

pokemon.setResourceUri(resourceUri);



Activity activity = buildActivity(pokemon);



RecordedRequest request = takeLastRequest();



//Perform the assertions

}
01SHADOW CLASSES
SHADOW CLASSES
• if your project structure prevents you from injecting mock
classes in unit tests

• any class can be swapped with a “shadow” class
SHADOWING A CLASS
1. Create a custom Robolectric runner

2. Declare shadowed classes in createClassLoaderConfig()
method

3. Implement shadow class

4. Add shadow classes to tests in @Config

5. Run tests with custom runner
CREATE A CUSTOM RUNNER
public class CustomRobolectricTestRunner extends RobolectricTestRunner {



/**

* Creates a runner to run {@code testClass}. Looks in your working directory for your
* AndroidManifest.xml file

* and res directory by default. Use the {@link Config} annotation to configure.

*

* @param testClass the test class to be run

* @throws InitializationError if junit says so

*/

public CustomRobolectricTestRunner(Class<?> testClass) throws InitializationError {

super(testClass);

}



/**

* Declare custom classes to be shadowed when shadow exist.

*/

public InstrumentationConfiguration createClassLoaderConfig() {

InstrumentationConfiguration.Builder builder =
InstrumentationConfiguration.newBuilder();


builder.addInstrumentedClass(GoogleCloudMessaging.class.getName());


return builder.build();

}

}
IMPLEMENT SHADOW CLASS
• create a new class with @Implements(OriginalClass.class)
annotation
• add @Implementation annotation to methods that “override”
behaviour from original class
• you can leave some methods unchanged

• if you wish to use an instance of OriginalClass in your
shadow class it must be annotated with @RealObject and
accessed through reflection
ADD SHADOWS TO TEST
• in order to make your shadows available in test add them to
@Config in your test:



@Config(shadows = {ShadowClass.class})
EXAMPLE SHADOW CLASS
@Implements(GoogleCloudMessaging.class)

public class ShadowGoogleCloudMessageing {



@Implementation

public void close() {

Log.d("GoogleCloudMessageing", "close()");

}



@Implementation

public void send(String to, String msgId, Bundle data) throws IOException {

Log.d("GoogleCloudMessageing", "send()");

}



@Deprecated

@Implementation

public synchronized String register(String... senderIds) throws IOException {

Log.d("GoogleCloudMessageing", "register()");

return "1234567890";

}



@Implementation

public String getMessageType(Intent intent) {

Log.d("GoogleCloudMessageing", "getMessageType()");

return "gcm";

}

}
01ASSERT J ANDROID
ASSERT J ANDROID
• https://github.com/square/assertj-android

• extension of AssertJ

• you can extend and set up your own assertions
EXAMPLE
//Check that name in details is displayed properly.

assertThat(activity.findViewById(R.id.name).getVisibility())

.isEqualTo(View.VISIBLE);

assertThat(((TextView) activity.findViewById(R.id.name))

.getText()).isEqualTo("Charizard");
SUMMARY
• use Robolectric for tests of a single Activity or Fragment
• use synchronous executors with Retrofit in tests
• use MockWebServer to easily mock out network responses
• use Shadows for classes that you can’t replace via
dependency injection
• AssertJ Android simplifies your assertions on Android stuff
CODE EXAMPLE
• https://github.com/infinum/Dagger-2-Example
Thank you!
Visit www.infinum.co or find us on social networks:
infinum.co infinumco infinumco infinum

Weitere ähnliche Inhalte

Was ist angesagt?

Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An IntroductionSam Brannen
 
Continuous Deployment Pipeline with maven
Continuous Deployment Pipeline with mavenContinuous Deployment Pipeline with maven
Continuous Deployment Pipeline with mavenAlan Parkinson
 
Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2Rossen Stoyanchev
 
Kirill Rozin - Practical Wars for Automatization
Kirill Rozin - Practical Wars for AutomatizationKirill Rozin - Practical Wars for Automatization
Kirill Rozin - Practical Wars for AutomatizationSergey Arkhipov
 
Ci jenkins maven svn
Ci jenkins maven svnCi jenkins maven svn
Ci jenkins maven svnAnkur Goyal
 
Version Management in Maven
Version Management in MavenVersion Management in Maven
Version Management in MavenGeert Pante
 
Arquillian : An introduction
Arquillian : An introductionArquillian : An introduction
Arquillian : An introductionVineet Reynolds
 
Selenium XPath Performance Problems in IE
Selenium XPath Performance Problems in IESelenium XPath Performance Problems in IE
Selenium XPath Performance Problems in IEClever Moe
 
Test it! Unit, mocking and in-container Meet Arquillian!
Test it! Unit, mocking and in-container Meet Arquillian!Test it! Unit, mocking and in-container Meet Arquillian!
Test it! Unit, mocking and in-container Meet Arquillian!Ivan Ivanov
 
Testing ansible roles with molecule
Testing ansible roles with moleculeTesting ansible roles with molecule
Testing ansible roles with moleculeWerner Dijkerman
 
Jenkins - Continuous Integration after Hudson, CruiseControl, and home built
Jenkins - Continuous Integration after Hudson, CruiseControl, and home builtJenkins - Continuous Integration after Hudson, CruiseControl, and home built
Jenkins - Continuous Integration after Hudson, CruiseControl, and home builtMark Waite
 
Eclipse IDE, 2019.09, Java Development
Eclipse IDE, 2019.09, Java Development Eclipse IDE, 2019.09, Java Development
Eclipse IDE, 2019.09, Java Development Pei-Hsuan Hsieh
 
Pipeline based deployments on Jenkins
Pipeline based deployments  on JenkinsPipeline based deployments  on Jenkins
Pipeline based deployments on JenkinsKnoldus Inc.
 
Apache Maven for SoftServe IT Academy
Apache Maven for SoftServe IT AcademyApache Maven for SoftServe IT Academy
Apache Maven for SoftServe IT AcademyVolodymyr Ostapiv
 
Selenium Tutorial
Selenium TutorialSelenium Tutorial
Selenium Tutorialprad_123
 
Testing in Ballerina Language
Testing in Ballerina LanguageTesting in Ballerina Language
Testing in Ballerina LanguageLynn Langit
 

Was ist angesagt? (20)

Maven basics
Maven basicsMaven basics
Maven basics
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An Introduction
 
Continuous Deployment Pipeline with maven
Continuous Deployment Pipeline with mavenContinuous Deployment Pipeline with maven
Continuous Deployment Pipeline with maven
 
Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2
 
Kirill Rozin - Practical Wars for Automatization
Kirill Rozin - Practical Wars for AutomatizationKirill Rozin - Practical Wars for Automatization
Kirill Rozin - Practical Wars for Automatization
 
Ci jenkins maven svn
Ci jenkins maven svnCi jenkins maven svn
Ci jenkins maven svn
 
Version Management in Maven
Version Management in MavenVersion Management in Maven
Version Management in Maven
 
Arquillian : An introduction
Arquillian : An introductionArquillian : An introduction
Arquillian : An introduction
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Selenium XPath Performance Problems in IE
Selenium XPath Performance Problems in IESelenium XPath Performance Problems in IE
Selenium XPath Performance Problems in IE
 
Test it! Unit, mocking and in-container Meet Arquillian!
Test it! Unit, mocking and in-container Meet Arquillian!Test it! Unit, mocking and in-container Meet Arquillian!
Test it! Unit, mocking and in-container Meet Arquillian!
 
Testing ansible roles with molecule
Testing ansible roles with moleculeTesting ansible roles with molecule
Testing ansible roles with molecule
 
Jenkins - Continuous Integration after Hudson, CruiseControl, and home built
Jenkins - Continuous Integration after Hudson, CruiseControl, and home builtJenkins - Continuous Integration after Hudson, CruiseControl, and home built
Jenkins - Continuous Integration after Hudson, CruiseControl, and home built
 
Eclipse IDE, 2019.09, Java Development
Eclipse IDE, 2019.09, Java Development Eclipse IDE, 2019.09, Java Development
Eclipse IDE, 2019.09, Java Development
 
Pipeline based deployments on Jenkins
Pipeline based deployments  on JenkinsPipeline based deployments  on Jenkins
Pipeline based deployments on Jenkins
 
Apache Maven for SoftServe IT Academy
Apache Maven for SoftServe IT AcademyApache Maven for SoftServe IT Academy
Apache Maven for SoftServe IT Academy
 
Arquillian
ArquillianArquillian
Arquillian
 
Selenium Tutorial
Selenium TutorialSelenium Tutorial
Selenium Tutorial
 
Maven
MavenMaven
Maven
 
Testing in Ballerina Language
Testing in Ballerina LanguageTesting in Ballerina Language
Testing in Ballerina Language
 

Ähnlich wie Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust

AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...Amazon Web Services
 
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 frameworksTomáš Kypta
 
Testing Microservices
Testing MicroservicesTesting Microservices
Testing MicroservicesAnil Allewar
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Roberto Franchini
 
WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaRainer Stropek
 
Apache DeltaSpike
Apache DeltaSpikeApache DeltaSpike
Apache DeltaSpikeos890
 
JLove - Replicating production on your laptop using the magic of containers
JLove - Replicating production on your laptop using the magic of containersJLove - Replicating production on your laptop using the magic of containers
JLove - Replicating production on your laptop using the magic of containersGrace Jansen
 
Javascript tdd byandreapaciolla
Javascript tdd byandreapaciollaJavascript tdd byandreapaciolla
Javascript tdd byandreapaciollaAndrea Paciolla
 
JBCN_Testing_With_Containers
JBCN_Testing_With_ContainersJBCN_Testing_With_Containers
JBCN_Testing_With_ContainersGrace Jansen
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestSeb Rose
 
How to use_cucumber_rest-assured_api_framework
How to use_cucumber_rest-assured_api_frameworkHow to use_cucumber_rest-assured_api_framework
How to use_cucumber_rest-assured_api_frameworkHarshad Ingle
 
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 EngineInphina Technologies
 
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 EngineIndicThreads
 
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 frameworksTomáš Kypta
 
Continuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECSContinuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECSAmazon Web Services
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-AppsSelenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-Appschrisb206 chrisb206
 
Using Java to implement SOAP Web Services: JAX-WS
Using Java to implement SOAP Web Services: JAX-WS�Using Java to implement SOAP Web Services: JAX-WS�
Using Java to implement SOAP Web Services: JAX-WSKatrien Verbert
 

Ähnlich wie Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust (20)

AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
 
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
 
Robolectric v2
Robolectric v2Robolectric v2
Robolectric v2
 
Testing Microservices
Testing MicroservicesTesting Microservices
Testing Microservices
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
 
Make it compatible
Make it compatibleMake it compatible
Make it compatible
 
WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA Austria
 
Apache DeltaSpike
Apache DeltaSpikeApache DeltaSpike
Apache DeltaSpike
 
JLove - Replicating production on your laptop using the magic of containers
JLove - Replicating production on your laptop using the magic of containersJLove - Replicating production on your laptop using the magic of containers
JLove - Replicating production on your laptop using the magic of containers
 
Javascript tdd byandreapaciolla
Javascript tdd byandreapaciollaJavascript tdd byandreapaciolla
Javascript tdd byandreapaciolla
 
JBCN_Testing_With_Containers
JBCN_Testing_With_ContainersJBCN_Testing_With_Containers
JBCN_Testing_With_Containers
 
Agile Swift
Agile SwiftAgile Swift
Agile Swift
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
How to use_cucumber_rest-assured_api_framework
How to use_cucumber_rest-assured_api_frameworkHow to use_cucumber_rest-assured_api_framework
How to use_cucumber_rest-assured_api_framework
 
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
 
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
 
Continuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECSContinuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECS
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-AppsSelenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
 
Using Java to implement SOAP Web Services: JAX-WS
Using Java to implement SOAP Web Services: JAX-WS�Using Java to implement SOAP Web Services: JAX-WS�
Using Java to implement SOAP Web Services: JAX-WS
 

Mehr von Infinum

Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...
Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...
Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...Infinum
 
Infinum Android Talks #20 - DiffUtil
Infinum Android Talks #20 - DiffUtilInfinum Android Talks #20 - DiffUtil
Infinum Android Talks #20 - DiffUtilInfinum
 
Infinum Android Talks #20 - Benefits of using Kotlin
Infinum Android Talks #20 - Benefits of using KotlinInfinum Android Talks #20 - Benefits of using Kotlin
Infinum Android Talks #20 - Benefits of using KotlinInfinum
 
Infinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactiveInfinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactiveInfinum
 
Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...
Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...
Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...Infinum
 
Infinum Android Talks #13 - Using ViewDragHelper
Infinum Android Talks #13 - Using ViewDragHelperInfinum Android Talks #13 - Using ViewDragHelper
Infinum Android Talks #13 - Using ViewDragHelperInfinum
 
Infinum Android Talks #14 - Log4j
Infinum Android Talks #14 - Log4jInfinum Android Talks #14 - Log4j
Infinum Android Talks #14 - Log4jInfinum
 
Infinum Android Talks #9 - Making your app location-aware
Infinum Android Talks #9 - Making your app location-awareInfinum Android Talks #9 - Making your app location-aware
Infinum Android Talks #9 - Making your app location-awareInfinum
 
Infinum Android Talks #14 - Gradle plugins
Infinum Android Talks #14 - Gradle pluginsInfinum Android Talks #14 - Gradle plugins
Infinum Android Talks #14 - Gradle pluginsInfinum
 
Infinum Android Talks #14 - Facebook for Android API
Infinum Android Talks #14 - Facebook for Android APIInfinum Android Talks #14 - Facebook for Android API
Infinum Android Talks #14 - Facebook for Android APIInfinum
 
Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...
Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...
Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...Infinum
 
Infinum Android Talks #18 - Create fun lists by Ivan Marić
Infinum Android Talks #18 - Create fun lists by Ivan MarićInfinum Android Talks #18 - Create fun lists by Ivan Marić
Infinum Android Talks #18 - Create fun lists by Ivan MarićInfinum
 
Infinum Android Talks #18 - In-app billing by Ivan Marić
Infinum Android Talks #18 - In-app billing by Ivan MarićInfinum Android Talks #18 - In-app billing by Ivan Marić
Infinum Android Talks #18 - In-app billing by Ivan MarićInfinum
 
Infinum Android Talks #18 - How to cache like a boss by Željko Plesac
Infinum Android Talks #18 - How to cache like a boss by Željko PlesacInfinum Android Talks #18 - How to cache like a boss by Željko Plesac
Infinum Android Talks #18 - How to cache like a boss by Željko PlesacInfinum
 
Infinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
Infinum iOS Talks #2 - VIPER for everybody by Damjan VujaklijaInfinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
Infinum iOS Talks #2 - VIPER for everybody by Damjan VujaklijaInfinum
 
Infinum iOS Talks #2 - Xamarin by Ivan Đikić
Infinum iOS Talks #2 - Xamarin by Ivan ĐikićInfinum iOS Talks #2 - Xamarin by Ivan Đikić
Infinum iOS Talks #2 - Xamarin by Ivan ĐikićInfinum
 
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho PolutaInfinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho PolutaInfinum
 
Infinum iOS Talks #1 - Swift done right by Ivan Dikic
Infinum iOS Talks #1 - Swift done right by Ivan DikicInfinum iOS Talks #1 - Swift done right by Ivan Dikic
Infinum iOS Talks #1 - Swift done right by Ivan DikicInfinum
 
Infinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran Burojevic
Infinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran BurojevicInfinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran Burojevic
Infinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran BurojevicInfinum
 
Infinum Android Talks #17 - A quest for WebSockets by Zeljko Plesac
Infinum Android Talks #17 - A quest for WebSockets by Zeljko PlesacInfinum Android Talks #17 - A quest for WebSockets by Zeljko Plesac
Infinum Android Talks #17 - A quest for WebSockets by Zeljko PlesacInfinum
 

Mehr von Infinum (20)

Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...
Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...
Infinum Android Talks #20 - Making your Android apps fast like Blue Runner an...
 
Infinum Android Talks #20 - DiffUtil
Infinum Android Talks #20 - DiffUtilInfinum Android Talks #20 - DiffUtil
Infinum Android Talks #20 - DiffUtil
 
Infinum Android Talks #20 - Benefits of using Kotlin
Infinum Android Talks #20 - Benefits of using KotlinInfinum Android Talks #20 - Benefits of using Kotlin
Infinum Android Talks #20 - Benefits of using Kotlin
 
Infinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactiveInfinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactive
 
Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...
Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...
Infinum iOS Talks #4 - Making your Swift networking code more awesome with Re...
 
Infinum Android Talks #13 - Using ViewDragHelper
Infinum Android Talks #13 - Using ViewDragHelperInfinum Android Talks #13 - Using ViewDragHelper
Infinum Android Talks #13 - Using ViewDragHelper
 
Infinum Android Talks #14 - Log4j
Infinum Android Talks #14 - Log4jInfinum Android Talks #14 - Log4j
Infinum Android Talks #14 - Log4j
 
Infinum Android Talks #9 - Making your app location-aware
Infinum Android Talks #9 - Making your app location-awareInfinum Android Talks #9 - Making your app location-aware
Infinum Android Talks #9 - Making your app location-aware
 
Infinum Android Talks #14 - Gradle plugins
Infinum Android Talks #14 - Gradle pluginsInfinum Android Talks #14 - Gradle plugins
Infinum Android Talks #14 - Gradle plugins
 
Infinum Android Talks #14 - Facebook for Android API
Infinum Android Talks #14 - Facebook for Android APIInfinum Android Talks #14 - Facebook for Android API
Infinum Android Talks #14 - Facebook for Android API
 
Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...
Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...
Infinum Android Talks #19 - Stop wasting time fixing bugs with TDD by Domagoj...
 
Infinum Android Talks #18 - Create fun lists by Ivan Marić
Infinum Android Talks #18 - Create fun lists by Ivan MarićInfinum Android Talks #18 - Create fun lists by Ivan Marić
Infinum Android Talks #18 - Create fun lists by Ivan Marić
 
Infinum Android Talks #18 - In-app billing by Ivan Marić
Infinum Android Talks #18 - In-app billing by Ivan MarićInfinum Android Talks #18 - In-app billing by Ivan Marić
Infinum Android Talks #18 - In-app billing by Ivan Marić
 
Infinum Android Talks #18 - How to cache like a boss by Željko Plesac
Infinum Android Talks #18 - How to cache like a boss by Željko PlesacInfinum Android Talks #18 - How to cache like a boss by Željko Plesac
Infinum Android Talks #18 - How to cache like a boss by Željko Plesac
 
Infinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
Infinum iOS Talks #2 - VIPER for everybody by Damjan VujaklijaInfinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
Infinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
 
Infinum iOS Talks #2 - Xamarin by Ivan Đikić
Infinum iOS Talks #2 - Xamarin by Ivan ĐikićInfinum iOS Talks #2 - Xamarin by Ivan Đikić
Infinum iOS Talks #2 - Xamarin by Ivan Đikić
 
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho PolutaInfinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
 
Infinum iOS Talks #1 - Swift done right by Ivan Dikic
Infinum iOS Talks #1 - Swift done right by Ivan DikicInfinum iOS Talks #1 - Swift done right by Ivan Dikic
Infinum iOS Talks #1 - Swift done right by Ivan Dikic
 
Infinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran Burojevic
Infinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran BurojevicInfinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran Burojevic
Infinum iOS Talks #1 - Becoming an iOS developer swiftly by Vedran Burojevic
 
Infinum Android Talks #17 - A quest for WebSockets by Zeljko Plesac
Infinum Android Talks #17 - A quest for WebSockets by Zeljko PlesacInfinum Android Talks #17 - A quest for WebSockets by Zeljko Plesac
Infinum Android Talks #17 - A quest for WebSockets by Zeljko Plesac
 

Kürzlich hochgeladen

%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 

Kürzlich hochgeladen (20)

%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust

  • 2. ROBOLECTRIC • http://robolectric.org/ • unit test framework • tests run in JVM on your machine
  • 5. ROBOLECTRIC SETUP 1. Add gradle dependencies 2. write test Application class 3. write test class 4. run tests
  • 6. 1. ADD DEPENDENCIES • make sure “Unit tests” is selected as Test Artifact under Build Variants • add the robolectric dependency in your app build.gradle file: // Robolectric
 testCompile 'junit:junit:4.12'
 testCompile 'org.hamcrest:hamcrest-library:1.3'
 testCompile 'org.apache.maven:maven-ant-tasks:2.1.3' // fixes issue on linux/mac
 testCompile('org.robolectric:robolectric:3.0')
  • 7. 2. WRITE TEST APPLICATION CLASS • all unit test code goes into test flavour • Test{applicationName} • must extend your application class • runs instead of application class in tests • should inject test dependencies
  • 8. 3. WRITE TEST CLASS • create new class in test flavor • specify runner with @RunWith annotation • add @Config annotation • add test methods and annotate them with @Test
  • 9. 3.5 TEST CONFIGURATION • constants property of @Config annotation is mandatory • options (except constants) can be specified in a file instead:
 /test/resources/robolectric.properties • for other options check:
 http://robolectric.org/configuring/ @RunWith(RobolectricGradleTestRunner.class)
 @Config(constants = BuildConfig.class, sdk = 21)
 public class DeckardActivityTest {
 
 @Test
 public void testSomething() throws Exception {
 assertTrue(Robolectric.setupActivity(DeckardActivity.class) != null);
 }
 }
  • 10. 4. RUN TESTS • from Android studio • ./gradlew clean test
  • 11. TEST REPORT • will be generated in:
 /app/build/reports/tests/{flavour}/index.html
 • if tests faill, gradle will print out the location of the report in console as well
  • 12. LOGS • to show Log.d() outputs add following in your @Before method:
 
 ShadowLog.stream = System.out;
  • 14. (A)SYNCHRONOUS EXECUTORS • unit tests run in a single thread
 • waiting for background threads complicates tests
 • solution: Synchronous executors (for Retrofit)
  • 15. SETUP • setting executor on Retrofit:
 
 
 
 • specify executor for networking and callbacks
 • for tests: both synchronous return new RestAdapter.Builder()
 ...
 .setExecutors(new BackgroundExecutor(), new CallbackExecutor())
 ...
 .build();
  • 16. SYNCHRONOUS EXECUTOR? • runs the queued runnable in the same thread
 • simple as that: public class SynchronousExecutor implements Executor { 
 @Override
 public void execute(Runnable command) {
 command.run();
 }
 }
  • 18. MOCK WEB SEVER • part of OkHttp library by Square
 • network responses must be mocked in unit tests • speed • consistency
  • 19. MOCK WEB SERVER DEPENDENCIES • add the MockWebServer dependency in your app build.gradle file: 
 
 • MockWebServer depends on OkHttp library • make sure that versions match testCompile ‘com.squareup.okhttp:mockwebserver:2.4.0'
  • 20. USING MOCKWEBSERVER 1. Instantiate MockWebServer 2. call start() method 3. get local server url by calling url(“/“) 4. inject local server url into networking module 5. enqueue responses using enqueue() method
  • 21. INSTANTIATING MOCK WEB SERVER • prepare and inject MockWebServer in @Before method (called before every @Test method) • stop MockWebServer in @After method (called after every @Test method)
  • 22. INSTANTIATING MOCK WEB SERVER • another option: • implement TestLifecycleApplication in Test application class
 • prepare and inject MockWebServer in
 beforeTest(Method) method in Test application class
 • stop MockWebServer in:
 afterTest(Method) in Test application class
  • 23. ENQUEUEING RESPONSES • enqueue(), MockResponse object • https://github.com/square/okhttp/blob/master/ mockwebserver/src/main/java/com/squareup/okhttp/ mockwebserver/MockResponse.java mockWebServer.enqueue(
 new MockResponse()
 .setResponseCode(200)
 .setBody(“Response body”)
 );
  • 24. WHAT ABOUT LARGE RESPONSES? 1. Store response body content to a file
 2. put the file inside /test/resources/ directory
 3. read the contents of the file in test: public static String readFromFile(String filename) {
 InputStream is = ResourceUtils.class.getClassLoader().getResourceAsStream(filename));
 return convertStreamToString(is);
 }
  • 25. CHECKING REQUESTS • mockWebServer.getRequestCount()
 • mockWebServer.takeRequest()
 • mockWebServer.takeRequest(long, TimeUnit)
  • 26. EXAMPLE @Test
 public void nameOk() throws Exception {
 PokemonTestApp.getMockWebServer().enqueue(
 new MockResponse()
 .setResponseCode(200)
 .setBody(ResourceUtils.readFromFile("charizard.json"))
 );
 
 String resourceUri = "api/v1/pokemon/6/";
 Pokemon pokemon = new Pokemon();
 pokemon.setResourceUri(resourceUri);
 
 Activity activity = buildActivity(pokemon);
 
 RecordedRequest request = takeLastRequest();
 
 //Perform the assertions
 }
  • 28. SHADOW CLASSES • if your project structure prevents you from injecting mock classes in unit tests
 • any class can be swapped with a “shadow” class
  • 29. SHADOWING A CLASS 1. Create a custom Robolectric runner
 2. Declare shadowed classes in createClassLoaderConfig() method
 3. Implement shadow class
 4. Add shadow classes to tests in @Config
 5. Run tests with custom runner
  • 30. CREATE A CUSTOM RUNNER public class CustomRobolectricTestRunner extends RobolectricTestRunner {
 
 /**
 * Creates a runner to run {@code testClass}. Looks in your working directory for your * AndroidManifest.xml file
 * and res directory by default. Use the {@link Config} annotation to configure.
 *
 * @param testClass the test class to be run
 * @throws InitializationError if junit says so
 */
 public CustomRobolectricTestRunner(Class<?> testClass) throws InitializationError {
 super(testClass);
 }
 
 /**
 * Declare custom classes to be shadowed when shadow exist.
 */
 public InstrumentationConfiguration createClassLoaderConfig() {
 InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); 
 builder.addInstrumentedClass(GoogleCloudMessaging.class.getName()); 
 return builder.build();
 }
 }
  • 31. IMPLEMENT SHADOW CLASS • create a new class with @Implements(OriginalClass.class) annotation • add @Implementation annotation to methods that “override” behaviour from original class • you can leave some methods unchanged
 • if you wish to use an instance of OriginalClass in your shadow class it must be annotated with @RealObject and accessed through reflection
  • 32. ADD SHADOWS TO TEST • in order to make your shadows available in test add them to @Config in your test:
 
 @Config(shadows = {ShadowClass.class})
  • 33. EXAMPLE SHADOW CLASS @Implements(GoogleCloudMessaging.class)
 public class ShadowGoogleCloudMessageing {
 
 @Implementation
 public void close() {
 Log.d("GoogleCloudMessageing", "close()");
 }
 
 @Implementation
 public void send(String to, String msgId, Bundle data) throws IOException {
 Log.d("GoogleCloudMessageing", "send()");
 }
 
 @Deprecated
 @Implementation
 public synchronized String register(String... senderIds) throws IOException {
 Log.d("GoogleCloudMessageing", "register()");
 return "1234567890";
 }
 
 @Implementation
 public String getMessageType(Intent intent) {
 Log.d("GoogleCloudMessageing", "getMessageType()");
 return "gcm";
 }
 }
  • 35. ASSERT J ANDROID • https://github.com/square/assertj-android
 • extension of AssertJ
 • you can extend and set up your own assertions
  • 36. EXAMPLE //Check that name in details is displayed properly.
 assertThat(activity.findViewById(R.id.name).getVisibility())
 .isEqualTo(View.VISIBLE);
 assertThat(((TextView) activity.findViewById(R.id.name))
 .getText()).isEqualTo("Charizard");
  • 37. SUMMARY • use Robolectric for tests of a single Activity or Fragment • use synchronous executors with Retrofit in tests • use MockWebServer to easily mock out network responses • use Shadows for classes that you can’t replace via dependency injection • AssertJ Android simplifies your assertions on Android stuff
  • 39. Thank you! Visit www.infinum.co or find us on social networks: infinum.co infinumco infinumco infinum