Viktor matSkevich

Testing with JUnit library for the Android platform

The basic approach to test development

Let's consider the use of JUnit library for testing Android app. As the application under test, a simple calculator was written. (activity_main.xml and MainActivity.java)

Now we'll briefly describe the algorithm of application work.

The first number is entered in the field, then the operation type is selected (addition, multiplication, division or subtraction). After that the entered value is saved, and the input field is overwritten. The second number is entered in the input field, then the "Calculate" button is pressed. The text field displays the result.

An example is shown in the picture below.
In MainActivity. java class all the logic of the application is provides. It is should remember that for easier covering of all app functional by tests, it is necessary to divide the functional into methods.

Also pay attention to the annotation to @VisibleForTesting, it is listed as in instances of classes and methods too. This annotation allows to take the objects or methods in testing. The main feature is if you take these objects not from the tests, the default access option will be "private". You can also manually set the access mode, for example:
Let's switch toward directly to the test itself. First, sign in build.gradle and paste the following relationship:
There is synchronize project, thereby pull up added by us relationship.

Then we go to the class that we want to test, and select the "Create Test".
After that the dialog box will appear.
The library for testing will be JUnit 4. We put a checkmark across the setUp and tearDown. This is the test lifecycle methods. After that we press "OK" button.

Here we choose the directory with "androidTest" name. You can read in details about these directories HERE.
We have received a new class of MainActivityTest.java in the result. Directly here our tests will be.

But that's not all. We still need to perform the following steps:
  1. Create an object of class ActivityTestRule, as well as add an annotation @Rule to this object. This object is a pointer to the test object.
  2. It implementing setUp() and tearDown() methods. We obtain activity in setUp() method, and we assign null to the object in the method tearDown().
  3. We inherit our class from Assert class. A number of methods for objects comparison is represented in Assert class. This class will greatly simplify the work with the test
Method which is designated by @Before annotation, fired at the beginning of the test. Typically, in the method body designated by this annotation, performed all the preparatory operations. For example, the download of valid data, etc.
@After annotation called immediately after the test completion
First test
Let's write the first test. Our task is to check the correctness of the cleanData() method's of MainActivity.java class work.

To do this, we will add the following code fragment in MainActivityTest.java class.
The test name is subjective. This article offers an option to register the name of the test as follows:

[Name function]_[Keys]_[Expected result]

where [Name function] - name of the main function for testing
[Keys] - values which supplies to the input of the test.

When there are many objects it is shouldn't to list it all but worth a try logically grouped.
[Expected result] - is expected result.

In this case, you can read the name of the test as follows: — Test cleanData() function: enter "2", then click "+" and re-introduce "2", as a result of the function cleanData() activity, all objects will be shown in its original state.

Now let's consider the fragments of the test code and sign it in more details.

The assertNotNull (Object) Function is checking the object on null. I advise you not to neglect this method and use it before calling functions in the object. It is typical check-up of object.

Earlier it was said about the annotation @VisibleForTesting. Let's add in MainActivity.java class the following methods, using this annotation:
These methods will useful to us in the process of writing test.

Let's return back to MainActivityTest.java class. At first, we get the view objects:
After that we use runOnUiThread(Runnable action) method, and perform a number of actions. It should remember that the tests are not run in the main thread, and all activities related directly to the view, must be called in the main thread.
"In fact, any actions associated with an interface can be called a model of user behavior."
Viktor Matskevich
Android developer
Let's check the correctness of the entered data presentation by following operations:
Then we obtain the clear field button and simulate clicking the button by performClick():
After pressing the cleanData () method should goes off. In this method, there is nulling of objects used both in the interface, and during the calculation result.
After all the operations performing we need to get the following result:
The log informs us that the test is passed.

Also in the test code the getInstrumentation().waitForIdleSync() function is calling. This function is required for thread synchronization, but it waits for all associated with the UI threads end. That is why it will not always work for the performance of tests with asynchronous tasks. This topic will be discussed in a separate article.

There are a lot of features in the writing of tests, we will talk about it later.
Thanks for reading!