Espresso Idling Resources

Tudip

Tudip

20 February 2020

Before going towards the ‘Espresso Idling  Resources’ I would like to introduce the ‘Espresso’.

Espresso

  • It’s the best platform to write a Platform UI test.
  •  It provides a well-maintained set of API’s.

Why ‘Automation Testing’

  • To test the complete application in which the user can write the scripts in his own way and his scripts can verify the expected and actual behavior of that application automatically.
  • In other words, it’s a kind of work to do a manual test in an automatic way.

Let’s move towards the  topic ‘Espresso Idling Resources’

  • When we are handling the application we need to wait for the application response and animations.
  • Like a normal user, expresso needs to wait for the ‘animation’ and the API calls these operations are ‘asynchronous operations‘.

Why we need ‘Espresso Idling Resources’

  • To handle the ‘asynchronous operations‘ in a better way because espresso has the ‘synchronization capabilities’.

Lets discussed the ‘Synchronous Capabilities

Espresso first very the certain condition to perform any action on the view

  • Verifies the currently asynchronous tasks.
  • Verifies the  ‘Idling Resources’ is ideal or not.
  • It also verifies the message queue to verify the running threads.

Way to handle the ‘Asynchronous Operations’

  • Adding calls to Thread.sleep()
    • As we know automation wants more tests to run on a short period of time and if we are using the delays to handle the ‘asynchronous operation’ it will be very difficult.
    • If you adding a pause for a constant period of time  then you can add
      ----------------
      
      Thread.sleep(durationInMillis);
      
      ------------------

      you have to put the time in the milliseconds. If you want to wait for the view till the view is not visible it is also possible by adding the logic to wait for the view till it is not visible and exit from the application once it is visible.
      Your code is like

      -------
      
       while( verify the visible of the view and time limit) {
      
      ---- pause for one millisecond of time ;
      
      }
      
      ------------

      This code also has a limitation we can only wait a specific period of time then your test starts failing. I am adding an example to better understand the scenario.

      -------------
      
      long currentTime = new Date().getTime(); // To get the current time
      
      long estimatedTime = currentTime + 15000; // Time after 15000 milliseconds.
      
      while (!isViewVisible(viewMatcher) || currentTime < estimatedTime) {
      
         currentTime = new Date().getTime();
      
         try {
      
            Thread.sleep(1); // wait for only 1 millisecond
      
         } catch (Exception e) {
      
         e.printStackTrace();
      
        }
      
      }
      
      --------------

Where to use

Here I am giving you a short description where you can use ‘Espresso Idling Resources’ after completing the full understanding of code I will provide you the details so that you can understand this scenario with an example.

  • When there is an API call and we have to wait for sometime.
  • To handle the ‘Animations’.
  • While establishing a connection with the databases.
  • Handling complex logic.

How and Where to use in a simple way

  • Add the dependency in your app level gradle file and you have to upgrade all the espresso versions also.
    -----
    
    implementation 'com.android.support.test.espresso:espresso-idling-resource:3.0.2'
    
    ----
  • Create a package on the development code folder.
  • Create java file ‘SimpleCountingIdlingresource’ and add the following code and extend this with the ‘IdlingResource’.
    --------------
    
    private final String mResourceName;
    
    
    
    
    private final AtomicInteger counter = new AtomicInteger(0);
    
    
    
    
    private volatile ResourceCallback callback;
    
    
    
    
    public SimpleCountingIdlingResource(String mResourceName) {
    
       this.mResourceName = checkNotNull(mResourceName);
    
    }
    
    
    
    
    @Override
    
    public String getName() {
    
       return mResourceName;
    
    }
    
    
    
    
    @Override
    
    public boolean isIdleNow() {
    
       return counter.get() == 0;
    
    }
    
    
    
    
    @Override
    
    public void registerIdleTransitionCallback(ResourceCallback callback) {
    
       this.callback = callback;
    
    }
    
    
    
    
    public void increment() {
    
           counter.getAndIncrement();
    
    }
    
    
    
    
    public void decrement() {
    
    
    
    
           int value = counter.decrementAndGet();
    
           if (value == 0 && callback != null) {
    
               callback.onTransitionToIdle();
    
           }
    
           if (value < 0) {
    
               throw new IllegalArgumentException("Counter has been corrupted");
    
           }
    
       }
    
    ----------------
  • Created the file to access the resources and handle in a better way.
  • It should be static methods as test case @BeforeClass need the static methods
    ---------
    
    private static final String RESOURCE = "GLOBAL";
    
     
    
    public static SimpleCountingIdlingResource simpleIdlingresource = new SimpleCountingIdlingResource(RESOURCE);
    
     
    
    public static void increment() {
    
       simpleIdlingresource.increment();
    
    }
    
     
    
    public static void decrement() {
    
       simpleIdlingresource.decrement();
    
    }
    
     
    
    public static IdlingResource getIdlingResource() {
    
       return simpleIdlingresource;
    
    }
    
    ----------

    This is just adding idling resources to our project then we have to register it to our test case.

    You have to register this in the @BrforeClass and in the @AfterClass you have to unregister.

    ---------------
    
    @BeforeClass
    
    public static void beforeClass() {
    
       IdlingRegistry.getInstance().register(EspressoIdlingResource.getIdlingResource());
    
    }
    
    @AfterClass
    
    public static void afterClass() {
    
       IdlingRegistry.getInstance().unregister(EspressoIdlingResource.getIdlingResource());
    
    }
    
    --------------------

    I am providing one example how to user idling resources in our project in different scenario

  • For API call
    ------------------------------------------------------------------
    API.loadData(new callback(){
    @Override
    public void onDataLoaded(Data data) { }
    @Overrride
    public void onFailure() { }
    })
    -------------------------------------------------------------------------------------------------------------------------------

    This is just an example of the API call. When the API call starts we are showing loader for the users to understand that the user has to wait. But as the espresso doest provide handles for that we have to add idling resources here.
    You have increased the counter and decrease when you want your app in the ideal state.

    ----------------------------------------
    
    
    EspressoIdlingResource.increment();
    API.loadData(new callback() {
    @Override
    public void onDataLoaded(Data data) {
    EspressoIdlingResource.decrement();
    }
    @Overrride
    public void onFailure() {
    EspressoIdlingResource.decrement();
    }
    })
    

    Note: You have to decrement the idling resources in the failure so after the failure your app should be ideal and able to perform the next task.

  • To handle the Animation
    •  If you are using animation for some duration then for that case also you have to handle idling resources.
    • Increment before the animation and decrement when the animation stops.
  •  While Using Handler
    • For such a case you have to increment the before starting the handler and decrement inside the handler.
      ============
      
      EspressoIdlingResource.increment();
      
       new Handler().postDelayed(()->{
      
         EspressoIdlingResource.decrement();
      
         imageIsLoaded= true;
      
      },500);
      
      ===============

Request a quote