Friday 19 May 2017

HB Blog 136: Android Automation Testing Using Espresso Framework.

Android tests are based on JUnit, and you can run them either as local unit tests on the JVM or as instrumented tests on an Android device. This post provides an introduction to the concepts and tools for building Android tests.
When using Android Studio to write any of your tests, your test code must go into one of two different code directories (source sets). For each module in your project, Android Studio includes both source sets, corresponding to the following test types:
Local unit tests:-
Located at module-name/src/test/java/.
These tests run on the local JVM and do not have access to functional Android framework APIs.

Instrumented tests:-
Located at module-name/src/androidTest/java/.
These are all tests that must run on an Android hardware device or an Android emulator.
Instrumented tests are built into an APK that runs on the device alongside your app under test. The system runs your test APK and your app under tests in the same process, so your tests can invoke methods and modify fields in the app, and automate user interaction with your app.
        Building Instrumented Unit Tests: Build complex unit tests with Android dependencies that cannot be satisfied with mock objects.
        Automating User Interface Tests: Create tests to verify that the user interface behaves correctly for user interactions within a single app or for interactions across multiple apps.
        Testing App Component Integrations: Verify the behavior of components that users do not directly interact with, such as a Service or a Content Provider.
However, the local unit tests and instrumented tests described above are just terms that help distinguish the tests that run on your local JVM from the tests that run on the Android platform (on a hardware device or emulator). The real testing types that you should understand when building a complete test suite are described in the following table.

TypeSubtype Description
Unit tests
Local Unit Tests Unit tests that run locally on the Java Virtual Machine (JVM). Use these tests to minimize execution time when your tests have no Android framework dependencies or when you can mock the Android framework dependencies.
Instrumented unit tests Unit tests that run on an Android device or emulator. These tests have access to Instrumentation information, such as the Context of the app you are testing. Use these tests when your tests have Android dependencies that mock objects cannot satisfy.
Integration Tests
Components within your app only This type of test verifies that the target app behaves as expected when a user performs a specific action or enters a specific input in its activities. For example, it allows you to check that the target app returns the correct UI output in response to user interactions in the app’s activities. UI testing frameworks like Espresso allow you to programmatically simulate user actions and test complex intra-app user interactions.
Cross-app Components This type of test verifies the correct behavior of interactions between different user apps or between user apps and system apps. For example, you might want to test that your app behaves correctly when the user performs an action in the Android Settings menu. UI testing frameworks that support cross-app interactions, such as UI Automator, allow you to create tests for such scenarios.
JUnit
You should write your unit or integration test class as a JUnit test class. The framework offers a convenient way to perform common setup, teardown, and assertion operations in your test.
A basic JUnit test class is a Java class that contains one or more test methods. A test method begins with the @Test annotation and contains the code to exercise and verify a single functionality (that is, a logical unit) in the component that you want to test.
The following snippet shows an example JUnit integration test that uses the Espresso APIs to perform a click action on a UI element, then checks to see if an expected string is displayed.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityInstrumentationTest {

    @Rule
    public ActivityTestRule mActivityRule = new ActivityTestRule<>(
            MainActivity.class);

    @Test
    public void sayHello(){
        onView(withText("Say hello!")).perform(click());

        onView(withId(R.id.textView)).check(matches(withText("Hello, World!")));
    }
}

In your JUnit 4 test class, you can call out sections in your test code for special processing by using the following annotations:
  • @Before: Use this annotation to specify a block of code that contains test setup operations. The test class invokes this code block before each test. You can have multiple @Before methods but the order in which the test class calls these methods is not guaranteed.
  • @After: This annotation specifies a block of code that contains test tear-down operations. The test class calls this code block after every test method. You can define multiple @After operations in your test code. Use this annotation to release any resources from memory.
  • @Test: Use this annotation to mark a test method. A single test class can contain multiple test methods, each prefixed with this annotation.
  • @Rule: Rules allow you to flexibly add or redefine the behavior of each test method in a reusable way. In Android testing, use this annotation together with one of the test rule classes that the Android Testing Support Library provides, such as ActivityTestRule or ServiceTestRule.
  • @BeforeClass: Use this annotation to specify static methods for each test class to invoke only once. This testing step is useful for expensive operations such as connecting to a database.
  • @AfterClass: Use this annotation to specify static methods for the test class to invoke only after all tests in the class have run. This testing step is useful for releasing any resources allocated in the @BeforeClass block.
  • @Test(timeout=): Some annotations support the ability to pass in elements for which you can set values. For example, you can specify a timeout period for the test. If the test starts but does not complete within the given timeout period, it automatically fails. You must specify the timeout period in milliseconds, for example: @Test(timeout=5000).
Use the JUnit Assert class to verify the correctness of an object's state. The assert methods compare values you expect from a test to the actual results and throw an exception if the comparison fails. Assertion classes describes these methods in more detail.

Monday 15 May 2017

HB Blog 135: Android Vertical Seekbar Tutorial.

Android and all mobile technologies are changing very rapidly and users need more attractive and new kinda control views. Most of us do get bored with same things everywhere.
A SeekBar is an extension of ProgressBar that adds a draggable thumb. The user can touch the thumb and drag left or right to set the current progress level or use the arrow keys.

But, lets say we need a seekbar view, a custom view which can progress by dragging thumb top or bottom for changing progress level. In these post, I will show how to create custom vertical seekbar in Android.

Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//CustomVerticalSeekbar.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.harshalbenake.verticalseekbar.views;


import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;

public class CustomVerticalSeekbar extends SeekBar {
    public CustomVerticalSeekbar(Context context) {
        super(context);
    }

    public CustomVerticalSeekbar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomVerticalSeekbar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }

    @Override
    public synchronized void setProgress(int progress) // it is necessary for
    // calling setProgress
    // on click of a button
    {
        super.setProgress(progress);
        onSizeChanged(getWidth(), getHeight(), 0, 0);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec,
                                          int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(), 0);

        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                setProgress(getMax()
                        - (int) (getMax() * event.getY() / getHeight()));
                onSizeChanged(getWidth(), getHeight(), 0, 0);
                break;

            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }
}

//MainActivity.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.harshalbenake.verticalseekbar;

import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;

import com.harshalbenake.verticalseekbar.views.CustomVerticalSeekbar;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CustomVerticalSeekbar customVerticalSeekbar=(CustomVerticalSeekbar)findViewById(R.id.customverticalseekbar);
        customVerticalSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean userAction) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }
}

//activity_main.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:gravity="center_horizontal">

    <com.harshalbenake.verticalseekbar.views.CustomVerticalSeekbar
        android:id="@+id/customverticalseekbar"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />
</LinearLayout>

Monday 1 May 2017

HB Blog 134: Improve Android Applications Performance.

Hey guys, I hope you liked my previous post on app performance HB Blog 132: Does Your Phone Get Hang? Know Why...  . I got few mails and suggestions for posting similar kind of posts. So, here is my one more post for optimize your app's performance in various ways to improve its responsiveness and battery efficiency.
Basically, user expects app to launch app faster as well as load UI without any glitches. App launch can take place in one of three states, each affecting how long it takes for your app to become visible to the user: cold start, warm start, and lukewarm start. In a cold start, your app starts from scratch. In the other states, the system needs to bring the app from the background to the foreground.
At the beginning of a state, the system has three tasks. These tasks are:
  1.     Loading and launching the app.
  2.     Displaying a blank starting window for the app immediately after launch.
  3.     Creating the app process.
As soon as the system creates the app process, the app process is responsible for the next stages. These stages are:
  1.     Creating the app object.
  2.     Launching the main thread.
  3.     Creating the main activity.
  4.     Inflating views.
  5.     Laying out the screen.
  6.     Performing the initial draw.
There are few safety measures we can take for improving application performance such as,
  1. Remove unused resource IDs:- We often declare and find a view using android:id="@+id/view". But, while actual calling it in java classes is not needed. Sometimes, we don't need any changes in that particular view so e can avoid creating this ids. Because, these ids are creating public static final constant variable which are taking up unneeded memory.
  2. Remove unused resource:- Many times we keep on changing UI/UX so in that case we might add up resource but won't remove it once they are unused, so try to remove unused resource it may be images, icons as well as layout and other XML.
  3. Minimize load on onCreate():-  When your application launches, the blank starting window remains on the screen until the system finishes drawing the app for the first time. At that point, the system process swaps out the starting window for your app, allowing the user to start interacting with the app. If you’ve overloaded Application.oncreate() in your own app, the system invokes the onCreate() method on your app object. Afterwards, the app spawns the main thread, also known as the UI thread, and tasks it with creating your main activity. From Android 4.4 (API level 19), logcat includes an output line containing a value called Displayed. This value represents the amount of time elapsed between launching the process and finishing drawing the corresponding activity on the screen. We understand that which activity is taking more time for loading and using tools like Method Tracer, Inline Tracer, etc. It also gives which methods are the culprits, most of the time it is onCreate() method. We need to optimize the load of these method by initializing resource that are needed at startup itself. We can also use methods such as reportFullyDrawn() to let the system know that your activity is finished with its lazy loading.
  4. Use injection framework like Dagger:- Whether the problem lies with unnecessary initialization or disk I/O, the solution calls for lazy-initializing objects: initializing only those objects that are immediately needed. We can have a dependency injection framework like Dagger that creates objects and dependencies are when they are injected for the first time.
  5. Use Asynchronous operation:- Using a background thread ("worker thread") removes strain from the main thread so it can focus on drawing the UI. In many cases, using AsyncTask provides a simple way to perform your work outside the main thread. AsyncTask automatically queues up all the execute() requests and performs them serially. This behavior is global to a particular process and means you don’t need to worry about creating your own thread pool. For background database operations we can use compile statements can be used. Have a look on similar post for more information, HB Blog 95: How To Compile SQL Statement Into Reusable Pre-compiled Statement Object???
  6. Avoid Virtualization:- If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster. It's also good practice, because you can tell from the method signature that calling the method can't alter the object's state. In native languages like C++ it's common practice to use getters (i = getCount()) instead of accessing the field directly (i = mCount). This is an excellent habit for C++ and is often practiced in other object oriented languages like C# and Java, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time. However, this is a bad idea on Android. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.
  7. Use Enhanced For Loop Syntax:- The enhanced for loop (also sometimes known as "for-each" loop) can be used for collections that implement the Iterable interface and for arrays. There are several alternatives for iterating through an array:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    static class Foo {
        int mSplat;
    }
    
    Foo[] mArray = ...
    
    public void zero() {
        int sum = 0;
        for (int i = 0; i < mArray.length; ++i) {
            sum += mArray[i].mSplat;
        }
    }
    
    public void one() {
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;
    
        for (int i = 0; i < len; ++i) {
            sum += localArray[i].mSplat;
        }
    }
    
    public void two() {
        int sum = 0;
        for (Foo a : mArray) {
            sum += a.mSplat;
        }
    }
    

    • zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop. 
    • one() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit. 
    • two() is fastest for devices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language.
  8. Avoid complex Layout Hierarchies:- Layouts are a key part of Android applications that directly affect the user experience. If implemented poorly, your layout can lead to a memory hungry application with slow UIs. The Android SDK includes tools to help you identify problems in your layout performance, which will help to implement smooth scrolling interfaces with a minimum memory footprint. In the same way a complex web page can slow down load time, your layout hierarchy if too complex can also cause performance problems. If your application UI repeats certain layout constructs in multiple places, you can use the <include/> and <merge/> tags to embed another layout inside the current layout. Beyond simply including one layout component within another layout, you might want to make the included layout visible only when it's needed, sometime after the activity is running. Deferring loading resources is an important technique to use when you have complex views that your app might need in the future. You can implement this technique by defining a ViewStub for those complex and rarely used views.
  9. Use View Holder for listview:- Listview is one of the most important and very excessively used view. The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread. The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread. A way around repeated use of findViewById() is to use the "view holder" design pattern. A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.
  10. Use 3rd party libraries carefully:- Actually, we use available libraries and resources for fasten our development time. It might not work as expected all the time and not all the design patterns and precautions are followed in these kinda libraries. So do explore complete libraries and then go for it. Android Arsenal is one of the interesting and helpful site which has categorized directory of libraries and tools for Android.