+ All Categories
Home > Documents > Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same...

Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same...

Date post: 28-May-2020
Category:
Upload: others
View: 6 times
Download: 0 times
Share this document with a friend
186
Production level Test Driven Development Fire Base Test Labs MVVM + DataBinding Dagger 2
Transcript
Page 1: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Production level Test Driven Development

Fire Base Test Labs

MVVM + DataBinding

Dagger 2

Page 2: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

About Me

Software Engineer

KAPIL BAKSHI

LOGISTICS + FINTECH + EDTECH

akapil167 [email protected]

FOODIE

TRAVELLER

MUSIC LOVER

SUSPENSE WATCHER

Page 3: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

About Me

International Conferences

[email protected]

DroidCon Beijing 2017

akapil167

HeisenBug Russia 2018

Android Makers France 2018

DroidKaigi Tokyo 2018

DroidCon Berlin 2018

Page 4: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

The Major Release is Coming

And The Bugs Come With It

Page 5: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

The War is Between The Features And The

Bugs

Page 6: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

And Make No Mistake

The Bugs Are Coming

Page 7: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

To Find A Solution

And That is Why We Have Gathered Here

Page 8: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

Which Framework to choose ?

Page 9: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

How to write Testable Code

Page 10: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

How to Test on Multiple Devices

Page 11: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

Unit Testing, Integration Testing or

End To End Tests

Page 12: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Flakiness and Its Mitigation

Same Code

Passing Failing

Ferocious Flaky

Page 13: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Flakiness and Its Mitigation

Same Code

Passing Failing?

ConcurrencyFlaky third party codeInfrastructure problems

Ferocious Flaky

Page 14: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Flakiness and Its Mitigation

Ferocious Flaky Hero Hermetic to the Rescue

Mocking Dependencies

Relying More on Unit Tests

Page 15: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Different Types Of Testing

Least Flaky

More Flaky

Most Flaky

Page 16: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Different Types Of Testing

Fast

Slower

Slowest

Page 17: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

Unit Testing, Integration Testing or

End To End Tests

Page 18: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Genuine Production Level Scenarios

Page 19: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Error Handling

Page 20: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Error Handling

Would you actually Turn Off the internet on your device ????

Would you actually stop your server ????

Page 21: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Error Handling

This would simply Defeat the purpose of Automation and make testing Cumbersome

Page 22: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

An App Accepting Different Types Of Orders

Page 23: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What would happen if you Don’t test this Hermetically

Page 24: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Handle Complex Order Lifecycle

Order Placed Packed Dispatched Delivered

App Packing team Dashboard Dispatchment team Dashboard Delivery App

Page 25: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

You would have to

Order Placed Packed Dispatched Delivered

App Packing team Dashboard Dispatchment team Dashboard Delivery App

HIT

External APIsFrom

Your

TEST CODE

Page 26: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Then you’ll realize

Page 27: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases

Page 28: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

It’s taking much longer to Write Tests to write than to actually Develop Features

Page 29: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

You are testing what you haven’t even coded

Page 30: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

The goal to test the code you have written gets

Farther

Farther

Farther

Farther

Page 31: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Then solution is quite simple

Let the Code Take Control Of Everything

Page 32: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Let’s

Explore

How

Page 33: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Local Storage

Mock Data Source

Business Logic

Persist

Query

Domain Layer

Data Layer

Page 34: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern - Advantages

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Mock Data Source

Business Logic

Persist

Query

Provides Abstraction of Data

Local Storage

Page 35: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern - Advantages

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Local Storage

Mock Data Source

Business Logic

Persist

Query

Makes the code Highly Maintainable and Extensible

Page 36: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern - Advantages

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Mock Data Source

Business Logic

Persist

Query

Makes the code Highly Configurable and Testable

Local Storage

Page 37: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern - In Action

Repository

Page 38: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository

OrdersDataSource

Interface which would be implemented by All the Data Sources and the Repository

public interface OrdersDataSource {

Observable<Order> getOrdersResponse();

}

Page 39: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic interface OrdersDataSource {

Observable<Order> getOrdersResponse();

}

OrdersDataSource

Method which would be overridden by all data sources

Page 40: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern - In Action

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Local Storage

Mock Data Source

Business Logic

Persist

Query

Let’s see the Repository Code

Page 41: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class OrdersRepository implements OrdersDataSource {

private final OrdersDataSource ordersDataSource;

private OrdersRepository ( @NonNull OrdersDataSource ordersDataSource ) { this.ordersDataSource = ordersDataSource;}

@Overridepublic Observable<AllOrdersResponse> getOrdersResponse() { return ordersDataSource.getOrdersResponse( ));}

OrdersRepository Implementing OrdersDataSource

Page 42: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class OrdersRepository implements OrdersDataSource {

private final OrdersDataSource ordersDataSource;

private OrdersRepository ( @NonNull OrdersDataSource ordersDataSource ) { this.ordersDataSource = ordersDataSource;}

@Overridepublic Observable<AllOrdersResponse> getOrdersResponse() { return ordersDataSource.getOrdersResponse( ));}

OrdersRepositoryAccepting a Data Source

Page 43: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class OrdersRepository implements OrdersDataSource {

private final OrdersDataSource ordersDataSource;

private OrdersRepository ( @NonNull OrdersDataSource ordersDataSource ) { this.ordersDataSource = ordersDataSource;}

@Overridepublic Observable<AllOrdersResponse> getOrdersResponse() { return ordersDataSource.getOrdersResponse());}

OrdersRepository

Using the data source to fetch

orders

Page 44: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern : Advantages

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Local Storage

Mock Data Source

Business Logic

Persist

Query

Let’s see OrderRemoteDataSource Code

Page 45: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class OrdersRemoteDataSource implements OrdersDataSource { @Inject NetworkApis networkApis;

@Override public Observable<AllOrdersResponse> getOrdersResponse() { networkApis.getOrders()); }

}

OrdersRemoteDataSource

Implementing OrdersDataSource

Page 46: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class OrdersRemoteDataSource implements OrdersDataSource { @Inject NetworkApis networkApis;

@Override public Observable<AllOrdersResponse> getOrdersResponse() { networkApis.getOrders()); }

}

OrdersRemoteDataSource

Fetching orders from the server

Page 47: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern - Advantages

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Local Storage

Mock Data Source

Business Logic

Persist

Query

Let’s see FakeDataSource Code

Page 48: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class FakeOrderDataSource implements OrdersDataSource {

public static Observable<AllOrdersResponse> ALL_ORDER_RESPONSE_OBSERVABLE;

@Override public Observable<Order> getOrdersResponse() { ALL_ORDER_RESPONSE_OBSERVABLE; }

}

FakeDataSource

We’ll be modifying ALL_ORDER_RESPONSE_OBSERVABLE as per different scenarios

Page 49: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class FakeOrderDataSource implements OrdersDataSource

. . .

public static void createAll_Order_Response() {

String errorMessage = null; boolean success = true; List<Order> orderList = new ArrayList<Order>(); ALL_ORDER_RESPONSE = new AllOrdersResponse ( success, errorMessage, orderList);

}

}

Creating a default response

FakeDataSource

Page 50: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class FakeOrderDataSource implements OrdersDataSource {

public void createAllOrderResponseWithServerErrorObservable(String errorMessage)

{ reCreateAll_Order_Response();

ALL_ORDER_RESPONSE.setErrorMessage(errorMessage);

ALL_ORDER_RESPONSE.setSuccess( false );

ALL_ORDER_RESPONSE_OBSERVABLE = Observable.just (ALL_ORDER_RESPONSE);

}

}

Creates All Orders Observable with an Error to

mock Server Error

FakeDataSource

Page 51: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class FakeOrderDataSource implements OrdersDataSource {

public void create_Exception_Error_Observable(String exceptionMessage) {

ALL_ORDER_RESPONSE_OBSERVABLE = Observable.<AllOrdersResponse>error(new NullPointerException(exceptionMessage));

}

Creates All Orders Observable with an Exception

FakeDataSource

Page 52: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repositorypublic class FakeOrderDataSource implements OrdersDataSource

. . .

public void createOrdersObservable(String...statuses) { reCreateAll_Order_Response(); for(String status : statuses) {

Order order = createOrderBasedOnStatus(status, new Random().nextInt(Integer.MAX_VALUE)); addOrders(order); } ALL_ORDER_RESPONSE_OBSERVABLE = Observable.just(getAllOrderResponse());

}

}

FakeDataSource

Creating order responseAs per different order statuses

Page 53: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Repository Pattern

Repository

Order

getOrders()

fetchOrderDetails()

updateOrderDetails()

Data Source

Cloud

Local Storage

Mock Data Source

Business Logic

Persist

Query

Now we know how to use different Data Sources

Page 54: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Now How do we interchange these Data Sources while Running our

Tests ??

Page 55: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Dependency Injection is the way to go!!

Now How do we interchange these Data Sources while Running our

Tests ??

Page 56: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Dependency Injection

The client delegates the responsibility of providing its dependencies to

external code (The Injector)

Without

The client having to build it.

Page 57: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Dependency Injection : Advantages

The client becomes highly Configurable and Reusable.

The Code becomes Decoupled.

Page 58: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Dependency Injection Using Dagger 2- In Action

Page 59: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Module Component Activity Fragment Any Other Class

Source of providing objects to be injected

Dagger 2: Constituents

Page 60: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Module Component Activity Fragment Any Other Class

Source of providing objects to be injected

Dagger 2: Constituents

Generates code which helps in injection

Page 61: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Module Component Activity Fragment Any Other Class

Source of providing objects to be injected

Dagger 2: Constituents

Generates code which helps in injection

This is where injection takes place

Page 62: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Modules In Dagger 2

@Modulepublic class OrdersModule {

@Provides@Singleton public OrdersRepository providesNotesRepository() { return OrdersRepository.getInstance( OrdersRemoteDataSource.getInstance()); }

}

Responsible for providing objects which can be injected

Page 63: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Modules In Dagger 2

@Modulepublic class OrdersModule {

@Provides@Singleton public OrdersRepository providesNotesRepository() { return OrdersRepository.getInstance( OrdersRemoteDataSource.getInstance()); }

}

Used for methods which provide objects for dependencies injection

Page 64: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Modules In Dagger 2

@Modulepublic class OrdersModule {

@Provides@Singleton public OrdersRepository providesNotesRepository() { return OrdersRepository.getInstance( OrdersRemoteDataSource.getInstance()); }

}Notice Remote Order Data Source is being used here

Page 65: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Modules In Dagger 2

@Modulepublic class OrdersTestModule extends OrdersModule {

@Provides@Singleton public OrdersRepository providesNotesRepository() { return OrdersRepository.getInstance( FakeOrdersDataSource.getInstance()); }

} Notice Fake Order Data Source is being used here

Page 66: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Module Component Activity Fragment Any Other Class

Source of providing objects to be injected

Dagger 2: Constituents

Page 67: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Components In Dagger 2@Singleton@Component (modules = { NotesModule.class, NetworkModule.class, OrdersModule.class})public interface AppComponent {

void inject(AddEditNoteActivity addEditNoteActivity);

void inject(AllNotesActivity allNotesActivity);

void inject(OrdersRemoteDataSource ordersRemoteDataSource);

void inject(AllOrdersActivity allOrdersActivity);}

This interface is used by Dagger 2 to generate code which uses the modules to fulfill the requested dependencies.

Page 68: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Module Component Activity Fragment Any Other Class

Source of providing objects to be injected

Dagger 2: Constituents

Generates code which helps in injection

Page 69: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

How does Injection Take Place

public class MyApplication extends Application {

private static AppComponent component;

public static AppComponent getComponent() { return component; }

public AppComponent createComponent() {

return DaggerAppComponent.builder() .networkModule(new NetworkModule(this)) .ordersModule(new OrdersModule()) .build(); }

DaggerAppComponent contains the generated

code to Configure Modules

Page 70: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

How does Injection Take Place

public class MyApplication extends Application {

private static AppComponent component;

public static AppComponent getComponent() { return component; }

public AppComponent createComponent() {

return DaggerAppComponent.builder() .networkModule(new NetworkModule(this)) .ordersModule(new OrdersModule()) .build(); }

Modules getting configured

Page 71: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

How does Injection Take Place

public class MyApplication extends Application {

private static AppComponent component;

public static AppComponent getComponent() { return component; }

public AppComponent createComponent() {

return DaggerAppComponent.builder() .networkModule(new NetworkModule(this)) .ordersModule(new OrdersTestModule()) .build(); }

Test Module getting configured

Page 72: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@Inject Annotation

public class AllOrdersActivity extends AppCompatActivity { @Inject OrdersRepository ordersRepository;

private AllOrdersViewModel allOrdersViewModel;

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyApplication.getComponent().inject(this); activityAllOrdersBinding = DataBindingUtil.setContentView(this, R.layout.activity_all_orders); } }

Injection Taking Place

Page 73: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Module Component Activity Fragment Any Other Class

Source of providing objects to be injected

Dagger 2: Constituents

Generates code which helps in injection

This is where injection takes place

Page 74: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

How to write Testable Code

Page 75: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

How to write Testable Code

Page 76: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Now That We Have The Tools Ready

Let’s Start Writing Test Cases

Page 77: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Three Approaches To Testing

Unit Instrumentation And Integration Testing Using

Espresso

Unit Testing Using Robolectric

Pure JVM Testing UsingMVVM

Which to Choose ?

Performance Analysis

Page 78: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Before That

Let’s talk about Appium a little

Page 79: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Before That

Black Box Testing

Page 80: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Before That

Black Box Testing

Code Agnostic

Page 81: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Before That

Black Box Testing

Code Agnostic

Only UI interactions

Page 82: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Before That

Black Box Testing

Code Agnostic

Only UI interactions

QA Centric

Page 83: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What we will be focusing on

White Box Testing

functions

Variables

UI as well

Classes

Page 84: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What we will be focusing on

White Box Testing

Code Aware

functions

Variables

UI as well

Classes

Page 85: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What we will be focusing on

White Box Testing

Code Aware

Unit Testing

functions

Variables

UI as well

Classes

Page 86: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What we will be focusing on

White Box Testing

Code Aware

Unit Testing

Dev Centric

functions

Variables

UI as well

Classes

Page 87: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Why Espresso ?

Closely Integrated With Android Studio

Page 88: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Why Espresso ?

Closely Integrated With Android Studio

No External Dependency eg. Selenium Server in case of Appium

Page 89: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Why Espresso ?

Closely Integrated With Android Studio

No External Dependency eg. Selenium Server in case of Appium

Can be used both for Unit and Integration Testing

Page 90: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Why Espresso ?

Closely Integrated With Android Studio

No External Dependency eg. Selenium Server in case of Appium

Can be used both for Unit and Integration Testing

Removes Flakiness By Mocking Intents

Page 91: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Hypnotic Effect of Espresso IntentsLet’s Mock’em

Page 92: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Test Runner

Test Application

TestModule

Instrumentation Tests Setup

Configures Test Application to replace Main Application

FakeDataSource

Page 93: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Test Runner

Test Application

TestModule

Instrumentation Tests Setup

FakeDataSourcePoints to the Test Module

Page 94: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Instrumentation Tests Source Set

Page 95: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Setting Up An Instrumentation Runner

defaultConfig {

applicationId "com.sinca.shoppy" minSdkVersion 19 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "com.sinca.shoppy.MyTestRunner"

}

In build.gradle

Test Runner Class

Page 96: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What does the Test Runner Do ??

public class MyTestRunner extends AndroidJUnitRunner {

@Override public Application newApplication(ClassLoader classLoader, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return super.newApplication(classLoader, TestMyApplication.class.getName(), context); }}

Replacing the application class With a Test

Application Class

Page 97: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What does the Test Application Do ??

public class TestMyApplication extends MyApplication {

@Override public AppComponent createComponent() {

return DaggerAppComponent.builder() .networkModule(new NetworkModule(this)) .ordersModule(new OrdersTestModule()) .build(); }

} Setting Up Test Modules

Page 98: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Test Runner

Test Application

TestModule

Instrumentation Tests Setup

FakeDataSource

Page 99: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Commands At a Glance

Page 100: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

@Rule public ActivityTestRule<AllOrdersActivity> mActivityTestRule = new ActivityTestRule<AllOrdersActivity>(AllOrdersActivity.class, true, false);

@Before public static void setUp() { FakeOrderDataSource.createALL_ORDER_RESPONSE_OBSERVABLE(); }

Provides functional testing of a single Activity

Page 101: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

@Rule public ActivityTestRule<AllOrdersActivity> mActivityTestRule = new ActivityTestRule<AllOrdersActivity>(AllOrdersActivity.class, true, false);

@Before public static void setUp() { FakeOrderDataSource.createALL_ORDER_RESPONSE_OBSERVABLE(); }

Creating the default response

Page 102: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

public void onExceptionError_checkIfSnacBarIsDispalyed() {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable( "Internet Security Exception" ); reloadOrdersActivity(); String text = mActivityTestRule.getActivity().getString(R.string. some_error_ocurred);

onView(allOf(withId(android.support.design.R.id. snackbar_text), withText(text))) .check( matches(isDisplayed())); }

Page 103: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

public void onExceptionError_checkIfSnacBarIsDispalyed () {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable("Internet Security Exception");

reloadOrdersActivity(); String text = mActivityTestRule.getActivity().getString(R.string. some_error_ocurred);

onView(allOf(withId(android.support.design.R.id. snackbar_text), withText(text))) .check( matches(isDisplayed()));

}

Creating Order Observable With An Exception

Page 104: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

FakeOrderDataSource.getInstance().create_Exception_Error_Observable("Internet Security Exception");

Replicating the entire scenario altogether

Page 105: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

public void onExceptionError_checkIfSnacBarIsDispalyed () {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable( "Internet Security Exception" );

reloadOrdersActivity(); String text = mActivityTestRule.getActivity().getString(R.string. some_error_ocurred);

onView(allOf(withId(android.support.design.R.id. snackbar_text), withText(text))) .check( matches(isDisplayed()));

}

Restarting the activity

Page 106: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

public void onExceptionError_checkIfSnacBarIsDispalyed () {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable( "Internet Security Exception" );

reloadOrdersActivity(); String text = mActivityTestRule.getActivity().getString(R.string.some_error_ocurred);

onView(allOf(withId(android.support.design.R.id. snackbar_text), withText(text))) .check( matches(isDisplayed()));

} Fetching string which would be displayed on the snackbar

Page 107: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

public class AllOrdersTest {

public void onExceptionError_checkIfSnacBarIsDispalyed () {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable( "Internet Security Exception" );

reloadOrdersActivity(); String text = mActivityTestRule .getActivity().getString(R.string. some_error_ocurred);

onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(text))) .check(matches(isDisplayed()));

} Checking If a SnackBar gets displayed with an appropriate text

Page 108: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Espresso Testing In Action

onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(text)))

.check(matches(isDisplayed())); }

ViewMatcher

ViewAssertion

Page 109: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Clicking on A Cancelled Order

@Testpublic void onCancelledOrderClick_checkIfCancelledOrderPageIsOpened() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

reloadOrdersActivity();

onView(withText(OrderLifeCycleConstants.STATUS_ORDER_CANCELLED)).perform(click());

onView(withId(R.id.order_cancelled_text_view)).check(matches(isDisplayed()));

}

Creating Orders List Observable

Page 110: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

You would have to

Order Placed Packed Dispatched Delivered

App Packing team Dashboard Dispatchment team Dashboard Delivery App

HIT

External APIsFrom

Your

TEST CODE

Page 111: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

Replicating the entire scenario altogether

Page 112: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Clicking on A Cancelled Order

@Testpublic void onCancelledOrderClick_checkIfCancelledOrderPageIsOpened() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

reloadOrdersActivity();

onView(withText(OrderLifeCycleConstants.STATUS_ORDER_CANCELLED)).perform(click());

onView(withId(R.id.order_cancelled_text_view)).check(matches(isDisplayed()));

}

ViewMatcher

Page 113: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Clicking on A Cancelled Order

@Testpublic void onCancelledOrderClick_checkIfCancelledOrderPageIsOpened() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

reloadOrdersActivity();

onView(withText(OrderLifeCycleConstants.STATUS_ORDER_CANCELLED)).perform(click());

onView(withId(R.id.order_cancelled_text_view)).check(matches(isDisplayed()));

}

ViewAction

Page 114: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Clicking on A Cancelled Order

@Testpublic void onCancelledOrderClick_checkIfCancelledOrderPageIsOpened() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

reloadOrdersActivity();

onView(withText(OrderLifeCycleConstants.STATUS_ORDER_CANCELLED)).perform(click());

onView(withId(R.id.order_cancelled_text_view)).check(matches(isDisplayed()));

} Checking if the correct page has opened

Page 115: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Server Error

@Testpublic void onServerError_checkIfSnackBarIsDisplayedWithCorrectMessage() {

FakeOrderDataSource.getInstance().createAllOrderResponseWithServerErrorObservable(SERVER_BUSY_MESSAGE);

reloadOrdersActivity();

onView(allOf(withId(android.support.design.R.id.snackbar_text),withText(SERVER_BUSY_MESSAGE))) .check(matches(isDisplayed()));

}

Page 116: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Replicating the entire scenario altogether

FakeOrderDataSource.getInstance().createAllOrderResponseWithServerErrorObservable(SERVER_BUSY_MESSAGE);

Page 117: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

It took

49 secs

45 secs to build &

Install the app

4 secs to run the 6 test cases

=+

Page 118: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

When to Use Espresso

For Integration Testing

To Test On Multiple Devices

To Test With Actual Data Sources

Page 119: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Mocks

Android SDK

To Run Tests Directly On

JVM

Not Required

Robolectric

Page 120: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Test Runner

Test Application

TestModule

Robolectric Tests Setup

Configures Test Application to replace Main Application

FakeDataSource

Page 121: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Test Runner

Test Application

TestModule

Robolectric Tests Setup

FakeDataSourcePoints to the Test Module

Page 122: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Unit Tests Source Set

Page 123: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Robolectric Test Class

@RunWith(RobolectricTestRunner.class)

@org.robolectric.annotation.Config(constants = BuildConfig.class, sdk = 21, shadows = {ShadowSnackbar.class},application = UnitTestingApplication.class)

public class AllOrdersActivityTest {

}

Setting Up Robolectric Config

Page 124: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Robolectric Test Class

@RunWith(RobolectricTestRunner.class)

@org.robolectric.annotation.Config(constants = BuildConfig.class, sdk = 21, shadows = {ShadowSnackbar.class},application = UnitTestingApplication.class)

public class AllOrdersActivityTest {

}

Setting Up Test Application to Inject Mocked Modules

Page 125: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Initialisation Before Every Test

@RunWith(RobolectricTestRunner.class)

public class AllOrdersActivityTest {

private void reloadOrdersActivity() {

activity = Robolectric.setupActivity(AllOrdersActivity.class);

ordersRecyclerView = (RecyclerView)activity.findViewById(R.id.orders_rc;

allOrdersViewModel = activity.getAllOrdersViewModel();}

}

Creating activity

Page 126: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Initialisation Before Every Test

@RunWith(RobolectricTestRunner.class)

public class AllOrdersActivityTest {

private void reloadOrdersActivity() {

activity = Robolectric.setupActivity(AllOrdersActivity.class);

ordersRecyclerView = (RecyclerView)activity.findViewById(R.id.orders_rc;

allOrdersViewModel = activity.getAllOrdersViewModel();}

}Referencing Recycler Views

Page 127: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Exception

@Testpublic void onExceptionErrorWhileFetchingOrders_checkIfSnacBarIsDisplayed() {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable("Internet Security Exception");

reloadOrdersActivity();

assertThat(activity.getString(R.string.some_error_ocurred),equalTo( ShadowSnackbar.getTextOfLatestSnackbar()));}

Creating Order Observable with Exception

Page 128: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

FakeOrderDataSource.getInstance().create_Exception_Error_Observable("Internet Security Exception");

Replicating the entire scenario altogether

Page 129: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Exception

@Testpublic void onExceptionErrorWhileFetchingOrders_checkIfSnacBarIsDisplayed() {

FakeOrderDataSource.getInstance().create_Exception_Error_Observable("Internet Security Exception");

reloadOrdersActivity();

assertThat(activity.getString(R.string.some_error_ocurred),equalTo( ShadowSnackbar.getTextOfLatestSnackbar()));}

Checking If Snackbar displays the correct text or not

Page 130: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@Testpublic void onOrdersLoaded_checkIfStatusLabellingOfOrderItemsIsCorrect() {

. . .

for(int i = 0; i < OrderLifeCycleConstants. ORDER_STATUSES_ARRAY.length; i++) {

View itemView = ordersRecyclerView.getChildAt(i);

TextView statusTextView = (TextView) itemView.findViewById(R.id.order_status_text_view);

assertTrue(statusTextView.getText().toString().equals(OrderLifeCycleConstants. ORDER_STATUSES_ARRAY[i])); }}

Referencing Views

Testing labelling Of Order Statuses

Page 131: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing labelling Of Order Statuses

@Testpublic void onOrdersLoaded_checkIfStatusLabellingOfOrderItemsIsCorrect() {

. . .

for(int i = 0; i < OrderLifeCycleConstants. ORDER_STATUSES_ARRAY.length; i++) {

View itemView = ordersRecyclerView .getChildAt(i);

TextView statusTextView = (TextView) itemView.findViewById(R.id. order_status_text_view);

assertTrue(statusTextView.getText().toString().equals(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY[i])); }} Checking If Every Order Displays The Correct Status Or Not

Page 132: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Clicking Of Orders

@Testpublic void onDeliveryOrderClick_checkIfDeliveryOrderPageIsOpened() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

reloadOrdersActivity();

ordersRecyclerView.getChildAt(0).performClick(); assertNextActivity(activity, DeliveryActivity.class);

}

Clicking on an Order Item

Page 133: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing Clicking Of Orders

@Testpublic void onDeliveryOrderClick_checkIfDeliveryOrderPageIsOpened() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

reloadOrdersActivity();

ordersRecyclerView.getChildAt(0).performClick(); assertNextActivity(activity, DeliveryActivity.class);

}Checking if correct activity has been opened or not

Page 134: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

Replicating the entire scenario altogether

Page 135: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

It took

23 secs

18 secs to Shadow Android Code To

JVM

5 secs to run the 6 test cases

=+

Page 136: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

When to Use Robolectric

For Testing Directly On JVM

Page 137: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

When to Use Robolectric

For Testing Directly On JVM

Very Useful When App Is Not Well Architectured

Page 138: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

When to Use Robolectric

For Testing Directly On JVM

Very Useful When App Is Not Well Architectured

Also very Helpful for testing view properties like colour, style etc.

Page 139: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

Which Framework to choose ?

Page 140: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

Which Framework to choose ?

Page 141: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing The View Model

Page 142: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Any Guesses

How much time it took ???

Page 143: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

It took

180 ms

To Run The Same Test Cases

Page 144: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

How Did It Happen???

Lets See…!!!

Page 145: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

View Model

public class AllOrdersViewModel {

public AllOrdersViewModel(

OrdersRepository repository) { ordersRepository = repository; }

private void loadOrders(final boolean showLoadingUI) { if (showLoadingUI) { dataLoading.set(true); }

ordersRepository.getOrdersResponse(new OrdersDataSource.LoadOrdersCallback() {

Accepting a Repository

Page 146: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

View Model

public class AllOrdersViewModel {

public AllOrdersViewModel(

OrdersRepository repository) { ordersRepository = repository; }

private void loadOrders(final boolean showLoadingUI) { if (showLoadingUI) { dataLoading.set(true); }

ordersRepository.getOrdersResponse(new OrdersDataSource.LoadOrdersCallback() {

Orders Are being fetched from the

Repository

Page 147: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@Override public void onCompleted() { }

@Override public void onError(Throwable e) {

dataLoading.set(false); snackbarText.set( exceptionErrorText ); }

@Override public void onNext(AllOrdersResponse allOrdersResponse) { dataLoading.set(false); if (allOrdersResponse.isSuccess()) {

ordersList.clear(); ordersList.addAll(allOrdersResponse.getOrders());

}

else { snackbarText.set(allOrdersResponse.getError_message()); }

Observable Which Would directly Update Views In The Activity

Page 148: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@Override public void onCompleted() { }

@Override public void onError(Throwable e) {

dataLoading.set(false); snackbarText.set( exceptionErrorText ); }

@Override public void onNext(AllOrdersResponse allOrdersResponse) { dataLoading.set(false); if (allOrdersResponse.isSuccess()) {

ordersList.clear(); ordersList.addAll(allOrdersResponse.getOrders());

}

else { snackbarText.set(allOrdersResponse.getError_message()); }

Observables Which Would directly Update Views In The Activity

Page 149: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@Override public void onCompleted() { }

@Override public void onError(Throwable e) {

dataLoading.set(false); snackbarText.set( exceptionErrorText ); }

@Override public void onNext(AllOrdersResponse allOrdersResponse) { dataLoading.set(false); if (allOrdersResponse.isSuccess()) {

ordersList.clear(); ordersList.addAll(allOrdersResponse.getOrders());

}

else { snackbarText.set(allOrdersResponse.getError_message()); }

Observables Which Would directly Update Views In The Activity

Page 150: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Layout Files ViewModel

<ProgressBar app:layout_constraintTop_toTopOf="@+id/cont_all_orders" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:elevation="2dp"

android:visibility="@{ allOrdersViewModel.dataLoading ? View.VISIBLE : View.GONE }" />

private final ObservableBoolean dataLoading = new ObservableBoolean(false);

dataLoading.set(true);

//After getting Response

dataLoading.set(false);

The Magic Of MVVM + DataBinding

Visibility Of This ProgressBar would depend on ObservableBoolean variable

Page 151: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

That Means I can Directly Test The View Model

And See Whether The Business Logic Works Fine Or Not

Page 152: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

YeSsssss

And Since The View Model is Simply a Java Class

Without Any Android Specific Code

The Tests Run Very

Fast

On

Page 153: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing ProgressBar

@Testpublic void afterSuccessFullOrdersLoading_CheckIfProgressBarIsNotDisplayed() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

AllOrdersViewModel allOrdersViewModel = constructAndGetAllOrdersViewModel (EXCEPTION_ERROR_SNACKBAR_TEXT);

allOrdersViewModel.loadOrders();

assertFalse(allOrdersViewModel.getDataLoading().get());

}

Page 154: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing ProgressBar

@Testpublic void afterSuccessFullOrdersLoading_CheckIfProgressBarIsNotDisplayed() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

AllOrdersViewModel allOrdersViewModel = constructAndGetAllOrdersViewModel (EXCEPTION_ERROR_SNACKBAR_TEXT);

allOrdersViewModel.loadOrders();

assertFalse(allOrdersViewModel.getDataLoading().get());

}

Instantiating The View Model

Page 155: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing ProgressBar

@Testpublic void afterSuccessFullOrdersLoading_CheckIfProgressBarIsNotDisplayed() {

FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);

AllOrdersViewModel allOrdersViewModel = constructAndGetAllOrdersViewModel (EXCEPTION_ERROR_SNACKBAR_TEXT);

allOrdersViewModel.loadOrders();

assertFalse(allOrdersViewModel.getDataLoading().get());

} Checking of dataLoading is false

Page 156: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

What’s New ??

Page 157: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Local DB Testing

Domain Layer

Presentation Layer

Data Layer

Page 158: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Local DB Testing

Room

Test Database Migrations

Test Database Queries

Page 159: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Local DB Testing

Domain Layer

Presentation Layer

Data Layer

Page 160: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Check out my in depth blog posts on medium

https://medium.com/@kapil.bakshi

Page 161: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

JUnitParams Support

@RunWith(JUnitParamsRunner.class)

public class PersonTest {

@Test

@Parameters({"17, false", "22, true" })

public void personIsAdult(int age, boolean valid) throws

Exception {

assertThat(new Person(age).isAdult(), is(valid));

}

}

Page 162: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing On Multiple Devices

Page 163: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing On Multiple Devices

Happy and Relaxed

After An Important

Release

Testing On Stage

Testing On PreProd

Testing On 3-4 Devices

Page 164: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing On Multiple Devices

Page 165: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Testing On Multiple Devices

Fire Base Test Labs

Page 166: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Robo Tests

Randomly Tests App’s UI

Can Supply Inputs for EditTexts

Can Choose Maximum Depth of Test Traversal

Page 167: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Run From Android Studio

Page 168: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Get Very Detailed Reports

Page 169: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Cons

Not Supported

1. Fewer Of Devices

2. Supports Only Android Instrumentation Tests

And Robo Tests

3. Network Speed Throttling Not Supported

Page 170: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

AWS Device Farm

Supports Different Types Of Tests

Page 171: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

AWS Device Farm

Testing At Different Network Speeds

Page 172: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

AWS Device Farm

More Devices To Test On

Page 173: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

The Only Con

Not Able To Run Specific TestNG Test Suites

Page 174: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Sauce Labs

Supports Different Testing Frameworks

Page 175: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Sauce Labs

Sauce Labs Acquired TestObject to enable testing on Real Devices

Page 176: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Sauce Labs

Just have to change The Url To Appium Hosted On TestObject

DesiredCapabilities capabilities = new DesiredCapabilities();

capabilities.setCapability("deviceName", deviceName); capabilities.setCapability("platformName", AppConfig.INSTANCE.get("platformName")); capabilities.setCapability("platformVersion", androidVersion); capabilities.setCapability("appPackage", appPackage); capabilities.setCapability("resetKeyboard", true); capabilities.setCapability("testobject_api_key", "89HG598ZXSD6YH78BEF9E5796C108A0F"); MobileDriver mobileDriver = new AndroidDriver(new URL("https://eu1.appium.testobject.com/wd/hub"), capabilities);

Page 177: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Cons

Not Supported

Network Speed Throttling Is Not Supported

Page 178: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

How to Test on Multiple Devices

Page 179: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

This talk will clear all your confusions

How to Test on Multiple Devices

Page 180: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

Oh Lord Of Test Driven Development

Cast Your Light Upon Us

Page 181: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

For The Release Is Critical

And Prone To Bugs

Page 182: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@akapil167

Page 183: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@akapil167

Entire Content Shared

Page 184: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@akapil167

Entire Content Shared

Grab It now

Page 185: Production level Test Driven Development · End To End Tests. Flakiness and Its Mitigation Same Code Passing Failing Ferocious Flaky. Flakiness and Its Mitigation Same Code Passing

@akapil167

Entire Content Shared

Follow to get latest updates


Recommended