Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to...
Transcript of Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to...
![Page 1: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/1.jpg)
Production level Test Driven Development
Fire Base Test Labs
MVVM + DataBinding
Dagger 2
![Page 2: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/2.jpg)
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 · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/3.jpg)
The Major Release is Coming
And The Bugs Come With It
![Page 4: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/4.jpg)
The War is Between The Features And The
Bugs
And The Bugs Come With It
![Page 5: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/5.jpg)
And Make No Mistake
The Bugs Are Coming
![Page 6: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/6.jpg)
And That is Why We Have Gathered Here
To Find A Solution
![Page 7: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/7.jpg)
This talk will clear all your confusions
Which Framework to choose ?
Umm.. Unit Testing, Instrumentation Testing or End To End Tests ??
Writing Testable Code
Running Tests On Different Devices
![Page 8: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/8.jpg)
Different Types Of Testing
1. Idea :- Testing Business Logic2. No external dependency3. Options :- Robolectric, JUnit, Mockito
![Page 9: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/9.jpg)
Different Types Of Testing
1. Idea :- Testing User Dependencies, Behaviour, Integration
2. Options :- Espresso, Robotium,Appium
![Page 10: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/10.jpg)
Flakiness and Its Mitigation
Same Code
Passing Failing
?
Concurrency
Flaky third party code
Infrastructure problems
Ferocious Flaky
![Page 11: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/11.jpg)
Flakiness and Its Mitigation
Same Code
Passing Failing
?
Concurrency
Flaky third party code
Infrastructure problems
Hero Hermetic to the Rescue
Mocking Dependencies
Relying More on Unit Tests
Ferocious Flaky
![Page 12: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/12.jpg)
Genuine Production Level
Scenarios
![Page 13: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/13.jpg)
Testing Error Handling
![Page 14: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/14.jpg)
Now to Test this
Would you actually Turn Off the internet on your device ????
Would you actually stop your server ????
![Page 15: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/15.jpg)
Now to Test this
This would simply Defeat the purpose of Automation and make testing Cumbersome
![Page 16: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/16.jpg)
An App Accepting Different Types Of Orders
![Page 17: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/17.jpg)
What would happen if you Don’t test this Hermetically
![Page 18: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/18.jpg)
Handle Complex Order Lifecycle
Order Placed Packed Dispatched Delivered
App Packing team Dashboard Dispatchment team Dashboard Delivery App
![Page 19: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/19.jpg)
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 20: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/20.jpg)
Then you’ll realize
It’s taking much Longer to write Test cases than to develop features
It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases
![Page 21: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/21.jpg)
Then you’ll realize
You are testing What You Haven’t Even Coded
![Page 22: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/22.jpg)
Then you’ll realize
The goal of testing The Code you have actually written gets
Farther .. Farther …. Farther………… Farther Away
![Page 23: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/23.jpg)
Then solution is quite simple
Let the Code Take Control Of Everything
![Page 24: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/24.jpg)
Let’s Explore How
![Page 25: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/25.jpg)
Repository Pattern
Repository
Order
getOrders()
fetchOrderDetails()
updateOrderDetails()
Data Source
Cloud
Local Storage
Mock Data Source
Business Logic
Persist
Query
Domain Layer
Data Layer
![Page 26: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/26.jpg)
Repository Pattern - Advantages
Repository
Order
getOrders()
fetchOrderDetails()
updateOrderDetails()
Data Source
Cloud
Local Storage
Mock Data Source
Business Logic
Persist
Query
Provides Abstraction of Data
![Page 27: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/27.jpg)
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 28: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/28.jpg)
Repository Pattern - Advantages
Repository
Order
getOrders()
fetchOrderDetails()
updateOrderDetails()
Data Source
Cloud
Local Storage
Mock Data Source
Business Logic
Persist
Query
Makes the code Highly Configurable and Testable
![Page 29: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/29.jpg)
Repository Pattern - In Action
Repository
![Page 30: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/30.jpg)
Repositorypublic interface OrdersDataSource {
interface LoadOrdersCallback {
void onGetOrdersResponse(Observable<AllOrdersResponse> ordersResponseObservable); }
void getOrdersResponse(@NonNull OrdersDataSource.LoadOrdersCallback callback);
}
OrdersDataSource
Interface which would be implemented by All the Data Sources and the Repository
![Page 31: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/31.jpg)
Repositorypublic class OrdersRepository implements OrdersDataSource {
private final OrdersDataSource ordersDataSource;
private OrdersRepository ( @NonNull OrdersDataSource ordersDataSource ) { this.ordersDataSource = ordersDataSource;}
@Overridepublic void getOrdersResponse(@NonNull final OrdersDataSource.LoadOrdersCallback callback) { ordersDataSource.getOrdersResponse(new OrdersDataSource.LoadOrdersCallback() { @Override public void onGetOrdersResponse(Observable<AllOrdersResponse> ordersResponseObservable) { callback.onGetOrdersResponse(ordersResponseObservable); } });}
OrdersRepository
Accepting a Data Source
![Page 32: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/32.jpg)
Repositorypublic class OrdersRemoteDataSource implements OrdersDataSource {
private static OrdersRemoteDataSource INSTANCE;
@Inject Retrofit retrofit;
@Override public void getOrdersResponse(@NonNull LoadOrdersCallback callback) {
MyApplication.getComponent().inject(this); NetworkApis networkApis = retrofit.create(NetworkApis.class); callback.onGetOrdersResponse(networkApis.getOrders());
}
public static OrdersRemoteDataSource getInstance() { if (INSTANCE == null) { INSTANCE = new OrdersRemoteDataSource(); } return INSTANCE; }}
OrdersRemoteDataSource
Fetching Orders From The Server Using
Retrofit
![Page 33: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/33.jpg)
Repositorypublic class FakeOrderDataSource implements OrdersDataSource {
@Override public void getOrdersResponse(@NonNull LoadOrdersCallback callback) {
callback.onGetOrdersResponse(getAllOrderResponseObservable());
}
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);
}
Fetching an Observable Of Mocked Orders
FakeDataSource
![Page 34: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/34.jpg)
Repositorypublic class FakeOrderDataSource implements OrdersDataSource {
@Override public void getOrdersResponse(@NonNull LoadOrdersCallback callback) { callback.onGetOrdersResponse(getAllOrderResponseObservable()); }
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);
}
}
Creates All Orders response which can be modified further
FakeDataSource
![Page 35: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/35.jpg)
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());}
}
Fetching an Observable Of Mocked Orders as per the
given statuses
FakeDataSource
![Page 36: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/36.jpg)
Repository
public class FakeOrderDataSource implements OrdersDataSource {
public void createAllOrderResponseWithServerErrorObservable(String errorMessage) {
reCreateAll_Order_Response(); addErrorToAllOrdersResponse(errorMessage); toggleSuccess(false); ALL_ORDER_RESPONSE_OBSERVABLE = Observable.just(getAllOrderResponse());
}
}
Creates All Orders Observable with an Error
to mock Server Error
FakeDataSource
![Page 37: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/37.jpg)
Repository
public 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 38: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/38.jpg)
Now How do we interchange these Data Sources while Running
our Tests ??
![Page 39: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/39.jpg)
Now How do we interchange these Data Sources while Running
our Tests ??
Dependency Injection is the way to go!!
![Page 40: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/40.jpg)
Dependency Injection
The client delegates the responsibility of providing its dependencies to external code
(The Injector)
Without
The client having to build it.
![Page 41: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/41.jpg)
Dependency Injection - Advantages
The client becomes highly Configurable and Reusable.
The Code becomes Decoupled.
![Page 42: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/42.jpg)
Dependency Injection Using Dagger 2- In Action
![Page 43: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/43.jpg)
Modules In Dagger 2
@Modulepublic class OrdersModule {
@Provides @Singleton public OrdersRepository providesNotesRepository() { return OrdersRepository.getInstance( OrdersRemoteDataSource.getInstance()); }
}
Responsible for providing objects which can be
injectedUsed for methods which provide
objects for dependencies injection
Notice Remote Order Data Source is being used here
![Page 44: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/44.jpg)
Modules In Dagger 2
public class OrdersTestModule extends OrdersModule {
@Override public OrdersRepository providesNotesRepository() { return OrdersRepository.getInstance( FakeOrderDataSource.getInstance()); }}
Test Order Module
Notice Mocked Order Data Source is being used
here
![Page 45: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/45.jpg)
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 46: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/46.jpg)
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(); }
@Override public void onCreate() { super.onCreate(); component = createComponent(); }}
DaggerAppComponent contains the generated code to Configure
Modules
![Page 47: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/47.jpg)
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(); }
@Override public void onCreate() { super.onCreate(); component = createComponent(); }}
Modules getting configured
![Page 48: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/48.jpg)
How does Injection Take Place While Testing
public class TestMyApplication extends Application {
@Override public AppComponent createComponent() { return DaggerAppComponent.builder() .networkModule(new NetworkModule(this)) .ordersModule(new OrdersTestModule()) .build(); }
Notice Test Module Getting Configured
![Page 49: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/49.jpg)
@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); } private void setViewModel() { allOrdersViewModel = findOrCreateViewModel(); activityAllOrdersBinding.setAllOrdersViewModel(allOrdersViewModel); }
@Override public void onResume() { super.onResume(); allOrdersViewModel.loadOrders(); }
Injection Taking Place
![Page 50: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/50.jpg)
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
Orders Are being fetched from the
Repository
![Page 51: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/51.jpg)
ordersResponseObservable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<AllOrdersResponse>() { @Override public void onCompleted() { }
@Override public void onError(Throwable e) { dataLoading.set(false); snackbarText.set(exceptionErrorText); e.printStackTrace(); }
@Override public void onNext(AllOrdersResponse allOrdersResponse) { dataLoading.set(false); if (allOrdersResponse.isSuccess()) { ordersList.clear(); ordersList.addAll(allOrdersResponse.getOrders()); } else { snackbarText.set(allOrdersResponse.getError_message()); }
Handling Exceptions
Orders Are being fetched from the
Repository
![Page 52: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/52.jpg)
Now That We Have The Tools Ready
Let’s Start Writing Test Cases
![Page 53: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/53.jpg)
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 54: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/54.jpg)
So, Why Espresso ?
Closely Integrated With Android Studio
No External Dependency eg. Selenium Server in case of Appium
![Page 55: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/55.jpg)
So, Why Espresso ?
Can be used both for Unit and Integration Testing
Removes Flakiness By Mocking Intents
![Page 56: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/56.jpg)
Hypnotic Effect of Espresso Intents
Let’s Mock’em
![Page 57: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/57.jpg)
Instrumentation Tests Source Set
![Page 58: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/58.jpg)
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 59: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/59.jpg)
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 60: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/60.jpg)
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 Mock Modules
![Page 61: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/61.jpg)
Espresso Commands At a Glance
![Page 62: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/62.jpg)
Espresso Commands At a Glance
![Page 63: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/63.jpg)
Espresso Testing In Action
public class AllOrdersTest {
@Rule public ActivityTestRule<AllOrdersActivity> mActivityTestRule = new ActivityTestRule<AllOrdersActivity>(AllOrdersActivity.class, true, false);
@BeforeClass public static void setUp() { FakeOrderDataSource.createALL_ORDER_RESPONSE_OBSERVABLE(); }
@Test 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())); }
Provides functional testing of a single Activity
Creating Order Observable With An Exception
![Page 64: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/64.jpg)
Espresso Testing In Action
public class AllOrdersTest {
@Rule public ActivityTestRule<AllOrdersActivity> mActivityTestRule = new ActivityTestRule<AllOrdersActivity>(AllOrdersActivity.class, true, false);
@BeforeClass public static void setUp() { FakeOrderDataSource.createALL_ORDER_RESPONSE_OBSERVABLE(); }
@Test 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 65: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/65.jpg)
Espresso Testing In Action
onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(text)))
.check(matches(isDisplayed())); }
ViewMatcher
ViewAssertion
![Page 66: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/66.jpg)
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 67: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/67.jpg)
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()));
}
View Action
![Page 68: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/68.jpg)
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()));
}
Clicking on a Cancelled OrderChecking if the
correct page has opened
![Page 69: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/69.jpg)
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 70: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/70.jpg)
It took
49 secs
45 secs to build &
Install the app
4 secs to run the 6 test cases
=
+
![Page 71: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/71.jpg)
When to Use Espresso
For Integration Testing
To Test On Multiple Devices
To Test With Actual Data Sources
![Page 72: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/72.jpg)
Mocks
Android SDK
To Run Tests Directly On
JVM
Not Required
![Page 73: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/73.jpg)
Unit Tests Source Set
![Page 74: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/74.jpg)
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
Setting Up Roblectric Config
![Page 75: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/75.jpg)
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_recycler_view);
allOrdersViewModel = activity.getAllOrdersViewModel();}
}
Referencing Views and View Model
Creating activity
![Page 76: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/76.jpg)
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
Creating Order Observable with
Exception
![Page 77: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/77.jpg)
Testing labelling Of Order Statuses
@Testpublic void onOrdersLoaded_checkIfStatusLabellingOfOrderItemsIsCorrect() {
FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY); reloadOrdersActivity(); 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
![Page 78: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/78.jpg)
Testing labelling Of Order Statuses
@Testpublic void onOrdersLoaded_checkIfStatusLabellingOfOrderItemsIsCorrect() {
FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY); reloadOrdersActivity();
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 79: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/79.jpg)
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
Checking If correct Activity has Opened or Not
![Page 80: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/80.jpg)
It took
23 secs
18 secs to Shadow Android Code To
JVM
5 secs to run the 6 test cases
=
+
![Page 81: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/81.jpg)
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 82: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/82.jpg)
Testing The View Model
![Page 83: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/83.jpg)
Any Guesses
How much time it took ???
![Page 84: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/84.jpg)
It took
180 milli secs
To Run The Same Test Cases
![Page 85: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/85.jpg)
How Did It Happen???
Lets Seee…!!!
![Page 86: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/86.jpg)
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
Orders Are being fetched from the
Repository
![Page 87: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/87.jpg)
ordersResponseObservable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<AllOrdersResponse>() { @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 88: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/88.jpg)
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 89: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/89.jpg)
ViewModel Activity
private final ObservableField<String> snackbarText = new ObservableField<>();
private void setupSnackBar() {
snackbarCallback = new Observable.OnPropertyChangedCallback() { @Override public void onPropertyChanged(Observable observable, int i) {
SnackbarUtils.showSnackbar(activityAllOrdersBinding.mainCord, allOrdersViewModel.getSnackbarText()); } }; allOrdersViewModel.snackbarText.addOnPropertyChangedCallback(snackbarCallback);
}
The Magic Of MVVM + DataBinding
Whenever ObservableField<String> changes, a Snackbar is shown in the
Activity with the updated value
private Observable.OnPropertyChangedCallback snackbarCallback;
@Overridepublic void onError(Throwable e) {
dataLoading.set(false);
snackbarText.set(exceptionErrorText);
e.printStackTrace();
}
![Page 90: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/90.jpg)
That Means I can Directly Test The View Model
And See Whether The Business Logic Works Fine Or Not
![Page 91: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/91.jpg)
YeSsssss
And Since The View Model is Simply a Java Class
Without Any Android Specific Code
The Tests Run Very
Fast On
![Page 92: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/92.jpg)
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
private AllOrdersViewModel constructAndGetAllOrdersViewModel(String errorText) {
return new AllOrdersViewModel(OrdersRepository.getInstance(FakeOrderDataSource.getInstance()), errorText);
}
![Page 93: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/93.jpg)
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() );
}Loading the orders and checking
that dataloading ObservableBoolean is false or not
![Page 94: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/94.jpg)
Testing Order Count
@Testpublic void onOrdersFetched_CheckIfOrdreCountIsCorrect() {
FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);
AllOrdersViewModel allOrdersViewModel = constructAndGetAllOrdersViewModel (EXCEPTION_ERROR_SNACKBAR_TEXT);
allOrdersViewModel.loadOrders();
assertEquals(3, allOrdersViewModel.getOrdersList().size());
}
Instantiating The View Model
![Page 95: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/95.jpg)
Testing Order Count
@Testpublic void onOrdersFetched_CheckIfOrdreCountIsCorrect() {
FakeOrderDataSource.getInstance().createOrdersObservable(OrderLifeCycleConstants.ORDER_STATUSES_ARRAY);
AllOrdersViewModel allOrdersViewModel = constructAndGetAllOrdersViewModel (EXCEPTION_ERROR_SNACKBAR_TEXT);
allOrdersViewModel.loadOrders();
assertEquals( 3, allOrdersViewModel.getOrdersList().size() );
}Loading the orders and checking
that orderList ObservableList<Order>
Count is 3 or not
![Page 96: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/96.jpg)
Testing On Multiple Devices
[Bonus]
![Page 97: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/97.jpg)
Testing On Multiple Devices
Happy and Relaxed
After An Important
Release
Testing On Stage
Testing On PreProd
Testing On 3-4 Devices
![Page 98: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/98.jpg)
Testing On Multiple Devices
![Page 99: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/99.jpg)
Testing On Multiple Devices
Fire Base Test Labs
![Page 100: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/100.jpg)
Robo Tests
Randomly Tests App’s UI
Can Supply Inputs for EditTexts
Can Choose Maximum Depth of Test Traversal
![Page 101: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/101.jpg)
Run From Android Studio
![Page 102: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/102.jpg)
Get Very Detailed Reports
![Page 103: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/103.jpg)
Cons
Not Supported
1. Less No. Of Devices
1. Supports Only Android Instrumentation Tests
And Robo Tests
1. Network Speed Throttling Not Supported
![Page 104: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/104.jpg)
AWS Device Farm
Supports Different Types Of Tests
![Page 105: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/105.jpg)
AWS Device Farm
Testing At Different Network Speeds
![Page 106: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/106.jpg)
AWS Device Farm
More Devices To Test On
![Page 107: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/107.jpg)
The Only Con
Not Able To Run Specific TestNG Test Suites
![Page 108: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/108.jpg)
Sauce Labs
Supports Different Testing Frameworks
![Page 109: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/109.jpg)
Sauce Labs
Sauce Labs Acquired TestObject to enable testing on Real Devices
![Page 110: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/110.jpg)
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 111: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/111.jpg)
Cons
Not Supported
Network Speed Throttling Is Not Supported
![Page 112: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/112.jpg)
Oh Lord Of Test Driven Development
Cast Your Light Upon Us
![Page 113: Production level Test Driven Development · It’s taking much longer to “Make Arrangements” to write Test Cases than to actually Write Test Cases. Then you’ll realize You are](https://reader036.fdocuments.in/reader036/viewer/2022080718/5f78d63074802b50c81afe1c/html5/thumbnails/113.jpg)
For The Release Is Critical
And Prone To Bugs