Top Banner
Tips and Tricks for Testing Lambda Expressions in Android David Carver CareWorks Tech Google Plus: David Carver Github: kingargyle
45

Tips and Tricks for Testing Lambda Expressions in Android

Feb 19, 2017

Download

Documents

David Carver
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Tips and Tricks for Testing Lambda Expressions in Android

Tips and Tricks for Testing Lambda Expressions in Android

David Carver

CareWorks Tech

Google Plus: David Carver

Github: kingargyle

Page 2: Tips and Tricks for Testing Lambda Expressions in Android

Agenda● Anonymous Classes and Lambdas

○ Definitions

○ Use in Android Applications

■ Lambdas in Android

● Retro Lambda

● Jack and Jill

● The Problems

● Tips and Tricks

Page 3: Tips and Tricks for Testing Lambda Expressions in Android
Page 4: Tips and Tricks for Testing Lambda Expressions in Android

Unit Testing vs Integration TestingUnit Tests try to test the smallest portion of code individually

and independently … for proper operation.

Integration Tests test blocks of code as a group. It occurs after

unit testing and before validation testing.

Page 5: Tips and Tricks for Testing Lambda Expressions in Android

About Anonymous Classes and Lambdas

Page 6: Tips and Tricks for Testing Lambda Expressions in Android

Anonymous ClassesAs defined by Java In a Nutshell, “an anonymous class is defined and instantiated in a

single succinct expression using the new operator”

Page 7: Tips and Tricks for Testing Lambda Expressions in Android

Where are Anonymous Classes Commonly Used in Android?● Runnables

● View Listeners

○ OnClickListener, OnLongClickListener, OnFocusChangeListener,

OnDragListener, OnTouchListener, etc

● Comparators

● Handler Callbacks

● Loaders

○ OnLoadCanceledListener

○ OnLoadCompleteListener

Page 8: Tips and Tricks for Testing Lambda Expressions in Android

What Are Lambda Expressions?Microsoft MSDN, July 20, 2015

A lambda expression is an anonymous function that you can use to create delegates or

expressions….you can write local functions that can be passed as arguments or returned

as the value of the function.

Page 9: Tips and Tricks for Testing Lambda Expressions in Android

What Are Lambda Expressions?Another way to pass code blocks around, but in a more compact syntax.

Lambda encourage you to do functional (what you want down, not specifically how it

is done) programming instead of an imperative (procedural, how it should be done).

Page 10: Tips and Tricks for Testing Lambda Expressions in Android

Lambdas vs Anonymous ClassesLambdas allow a cleaner syntax for Anonymous Classes that contain a

single method that needs to be implemented .

Page 11: Tips and Tricks for Testing Lambda Expressions in Android

Lambda onClickListener implementationLambda syntax for an onClickListener representation.

Page 12: Tips and Tricks for Testing Lambda Expressions in Android

Android and Lambdas● RetroLambda - https://github.com/orfjackal/retrolambda

○ Backports the Java 8 support for Lambdas

○ Allows the use Lambdas all the way back to Java 5.

○ Generates code at compile time

○ Gradle Plugin - https://github.com/evant/gradle-retrolambda

● Jack and Jill - http://tools.android.com/tech-docs/jackandjill

○ Android specific compiler

○ Natively supports Java 8 and Lambdas

○ Only supports back to Java 7

■ No Java 6 support for older devices

○ Will be the standard android compiler going forward.

Page 13: Tips and Tricks for Testing Lambda Expressions in Android

So What is the Problem?Lambdas as used in Java currently, are a cleaner syntax for single method anonymous

classes.

● Trying to write tests leads to writing integration tests

● Leads to duplication of Code

● Can lead to hard to maintain code

○ Multiple inline overrides embedded multiple levels deep.

● Testing code that requires a Framework or other layers to work leads to tests that

need more setup.

○ Can lead to longer execution time of your tests

○ More difficult to setup tests

Page 14: Tips and Tricks for Testing Lambda Expressions in Android

PerformanceLambda Expressions are not as

optimized by the compiler

currently as standard imperative

ways of accomplishing the same

thing.

Imperative is still faster in the

following areas:

● Iterators

● For Each

Benchmarks are tricky and can be

misleading, but be careful going

hog wild with lambdas as they can

introduce slow points in your code.

http://blog.takipi.com/benchmark-how-java-8-lambdas-and-streams-can-make-your-code-5-times-slower/

Page 15: Tips and Tricks for Testing Lambda Expressions in Android

Anonymous Classes plague Graphical User Interface work.

They are convenient. However, hard to unit test.

Lambdas can be used many places that you would

implement an Anonymous class.

They suffer the same testing problem as Anonymous

Classes.

It leads to integration testing and not unit testing.

Page 16: Tips and Tricks for Testing Lambda Expressions in Android

HOW DO WE BRING ORDER OUT OF CHAOS?

Page 17: Tips and Tricks for Testing Lambda Expressions in Android

AVOID USING ANONYMOUS CLASSES!

Page 18: Tips and Tricks for Testing Lambda Expressions in Android

AVOID USING LAMBDAS!

Page 19: Tips and Tricks for Testing Lambda Expressions in Android

DO NOT OVER USE LAMBDASBECAUSE THEY ARE CONVENIENT.

Page 20: Tips and Tricks for Testing Lambda Expressions in Android

DO WHAT IS RIGHT.NOT WHAT IS EASY.

Page 21: Tips and Tricks for Testing Lambda Expressions in Android

You are going to use them anyways right?

Page 22: Tips and Tricks for Testing Lambda Expressions in Android

Tips and Tricks

Page 23: Tips and Tricks for Testing Lambda Expressions in Android

Where are Lambdas Commonly Used in Android?● RXJava and RXJava for Android

○ Anywhere the Action class/interface would normally be implemented.

○ Anywhere where anonymous inline overrides would have been used.

○ If you are doing RX… you are probably using Lambdas otherwise you go insane.

● Implementation of Interfaces

○ Handlers

○ Runnables

○ Listeners

○ Any place you could use an anonymous class with a single method.

All of these places are also where you typically have Unit Testing pain points.

Page 24: Tips and Tricks for Testing Lambda Expressions in Android

What is RXJava and RX Android?A library for composing asynchronous and

event-based programs by using observable

sequences.

It is an implementation of ReactiveX (Reactive

Extensions).

https://github.com/ReactiveX/RxJava/wiki

Page 25: Tips and Tricks for Testing Lambda Expressions in Android

RXJava Syntax for Java 7

Page 26: Tips and Tricks for Testing Lambda Expressions in Android

RXJava Syntax for Java 8

Page 27: Tips and Tricks for Testing Lambda Expressions in Android

Implement Concrete Class from Interface● Simple POJO

● Typically the fastest to execute

● Typically the least complicated to setup

● Can be reused in other places in your application.

Many Android examples use Anonymous Classes. Stop following these examples.

Page 28: Tips and Tricks for Testing Lambda Expressions in Android

Implement the Interface on a View/Fragment/Activity

This is fine .... until your class starts becoming a GOD class that

wants to do everything.

Avoid GOD classes… they become a nightmare to test.

Page 29: Tips and Tricks for Testing Lambda Expressions in Android

Easier View Listener Testing

Page 30: Tips and Tricks for Testing Lambda Expressions in Android

Robolectric and Butterknife● Robolectric

○ Unit Test Framework that runs on your computer

■ No Device needed

■ No Simulator

■ Simulates Android

■ Runs on your machine.

● ButterKnife

○ Developed by Jake Wharton

○ Part of the Square Development Stack

○ Generates Code based on Annotations

■ @BindView, @BindInt, @BindBoolean

■ @OnClick, @OnLongClick

Page 31: Tips and Tricks for Testing Lambda Expressions in Android

ButterKnife onClick Binding Example

Page 32: Tips and Tricks for Testing Lambda Expressions in Android

ButterKnife onClick Binding Example

Page 33: Tips and Tricks for Testing Lambda Expressions in Android

ButterKnife Testing Advantages● No Anonymous classes

● Lambdas are not necessary

● Less Likely to lead to an Integration Test

○ Allows for a pure unit test without executing more code than necessary

● Simpler tests

○ Leading to faster execution of the tests

● Cleaner Code leading to easier maintenance

● Can Bind onClicks to multiple views allowing for easier code re-use.

Page 34: Tips and Tricks for Testing Lambda Expressions in Android

Testing Lambdas in RXJava● RXJava allows for easier implementation of Async Tasks

○ File operations

○ Database Acccess

○ Remote Procedure Calls

○ Any type of Background Tasks

○ Can support Event Bus style notifications

● Lambdas can make writing RXJava Observables cleaner

○ No Messy inline override syntax

● However, RXJava leads to more Integration Style Tests

● Tests are harder to setup, and more complicated to verify and isolate.

Page 35: Tips and Tricks for Testing Lambda Expressions in Android

Common RXJava Test Situations● Subscribers and Error conditions

● Subjects

● Map Flatteners

● Joins

The simplest way to test these is to extract the functionality to a method, and test the

code that is intended to be executed separately.

Page 36: Tips and Tricks for Testing Lambda Expressions in Android

Extract to Method

Page 37: Tips and Tricks for Testing Lambda Expressions in Android

Extract to Method

Extracting this out allows for testing of the expected behavior of this code without executing the subscribe directly. It also keeps your code potentially cleaner.

Page 38: Tips and Tricks for Testing Lambda Expressions in Android

RXJava TestSubscriber● Allows you to execute the subscribe, and error portions of an RXJava Observable.

● Provides the simplest method for executing the least amount of code possible.

● Use in combination with Mockito/EasyMock to provide mocks for the

Observables that are being subscribed too.

● This is still an Integration Test

○ Requires RXJava Framework to execute in order to test the conditions and code in the Lambda

expression.

○ Less Complicated though than trying to Mock Out the RXJava Framework itself.

Page 39: Tips and Tricks for Testing Lambda Expressions in Android

RXJava Testing Error Conditions

Page 40: Tips and Tricks for Testing Lambda Expressions in Android

RXJava TestSubscriber - code under test

Page 41: Tips and Tricks for Testing Lambda Expressions in Android

RXJava TestSubscriber - subscribe

Page 42: Tips and Tricks for Testing Lambda Expressions in Android

RXJava - Testing Subjects with Schedulers

Page 43: Tips and Tricks for Testing Lambda Expressions in Android

Summary● Leverage Lambdas

○ Make sure you are using for the right reasons, not because you can.

○ They can provide cleaner code, but can make it more complicated to test.

● Prefer implementing your Interfaces as re-usable classes

○ Easier to strictly unit test

○ Reduce code duplication

● Leverage Butterknife when possible for binding click events

○ Allows simpler tests

○ Cleaner test setup and execution

● Consider extracting lambdas that contain complicated code to either Classes or

methods.

Page 44: Tips and Tricks for Testing Lambda Expressions in Android

Resources● RXJava - https://github.com/ReactiveX/RxJava

● RXJava for Android - https://github.com/ReactiveX/RxAndroid

● RetroLambda - https://github.com/orfjackal/retrolambda

● ButterKnife - http://jakewharton.github.io/butterknife/

● Robolectric - https://github.com/robolectric/robolectric

● Mockito - http://site.mockito.org/

● Testing RX Java Observables -

https://labs.ribot.co.uk/unit-testing-rxjava-6e9540d4a329#.9ydk0xq9b

● Testing Lambda Expressions -

http://radar.oreilly.com/2014/12/unit-testing-java-8-lambda-expressions-and-strea

ms.html

Page 45: Tips and Tricks for Testing Lambda Expressions in Android

Resources