NOW Hiring

Quick links

This tutorial describes how to write unit and instrumentation tests for your Android application. It also covers the usage of Mockito for Android tests and describes how to execute these tests via Android studio and Gradle. This tutorial assumes that you are familiar with Android programming in general.

1. Why is testing important for Android applications?

1.1. Testing Android applications

Android applications run on devices with limited memory, CPU power and power supply. The behavior of the application also depends on external factors like connectivity, general system utilization, etc.

Therefore, it is very important to debug, test and optimize your Android application. Having a reasonable test coverage for your Android application helps you to enhance and maintain the Android application.

As it is not possible to test Android applications on all possible device configurations, it is a common practice to run Android tests on typical device configurations. You should test your application at least on one device with the lowest possible configuration. In addition you should test on one device with the highest available configuration, e.g., pixel density, screen resolution to ensure that it works fine on these devices.

Unit testing for Android can be classified into:

  • Local unit tests - tests which can run on the JVM

  • Instrumented unit tests - tests which require the Android system

Android testing categories

If possible, you should prefer to use local tests as the test execution is much faster compared to the time required to deploy and run the test on an Android device.

1.2. Tooling support for Android testing

In 2015 the tooling and framework support for testung Android applications was hugely improved.

The Android Testing Support library (ATSL) support testing with a JUnit 4-compatible test runner (AndroidJUnitRunner). You can run unit tests either on the Java virtual machine or on an Android runtime. Also, Google introduced a user interface testing framework called Espresso which makes is easy to develop user interface tests for Android applications.

1.3. Unit tests (local tests)

The Android Gradle plug-in supports running Android unit tests on the JVM. To enable this, this Gradle plug-in creates a special version of the android.jar (also known as the Android mockable jar). This file is provided to the unit test so that all fields, methods and classes are available. Any call to the Android mockable JAR results, by default, in an exception.

Therefore, if your classes do not call the Android API, you can use the JUnit test framework (or any other Java testing framework) without any restrictions. If you have dependencies to the Android API, these dependencies in your code must be replaced for the unit tests, e.g., via a mocking framework like Mockito. See Activating default return values for mocked methods in android.jar for information how to define that default values should be returned from the Android mockable jar.

The advantages of running your tests on the JVM is that the execution speed of the tests is extremely fast compared to tests running on Android.

1.4. Instrumented tests for testing Java classes which use the Android API

If you want to test code which use the Android API, you need to run these tests on an Android device. Unfortunately, this makes the execution time of the tests longer.

1.5. What to test on Android applications

You should focus your Android tests on testing the business logic of your application. A good rule of thumb is to have the following distribution of tests:

  • 70-80 % unit tests to ensure stability of your code basis

  • 20-30 % functional tests to ensure that the application really works

  • some cross functional tests if your application integrates intensively with other Application components

Testing Strategy for Android

Another important criteria for testing is if you only test your own application or if you test the integration with other applications. If you run tests within your application you can use testing frameworks which require some knowledge about your application, e.g., the view IDs.

1.6. Testing preconditions

It is good practice in Android testing to have one method called testPreconditions() which tests the pre-conditions for all other tests. If this method fails, you know immediately that the assumptions for the other tests have been violated.

2. Android project structure and test folder creation

2.1. Android project organization for tests

The preferred way of organizing tests is based on a convention. In your application project, you should use the following base folder structure for your code organization, this is also the structure the project wizard creates.

  • app/src/main/java- for your source code of your main application build

  • app/src/test/java - for any unit test which can run on the JVM

  • app/src/androidTest/java - for any test which should run on an Android device

If you follow this conversion than the Android build system can automatically run the unit tests on the JVM and the Android tests on the Android device.

2.2. Solving the "error duplicate files in path" error

If you receive the following error message: "error duplicate files in path. Path in archive: LICENSE.txt" you can add the following to your app/gradle.build file.

android {
    packagingOptions {
    exclude 'LICENSE.txt'
    }
}

3. Unit testing on the JVM

3.1. Unit testing in Android

Android uses the term unit tests for tests which can run on a local JVM on the development machine instead of the Android Runtime.

A unit test verifies in isolation the functionality of a certain component. For example, assume a button in an Android activity is used to start another activity. A unit test would determine if the corresponding intent was issued, not if the second activity was started.

The unit tests are executed against a modified version of the android.jar Android library where all final modifiers have been stripped off. This allow you to mocking libraries, like Mockito. All methods in the used android.jar file throw exceptions (by default). This is to make sure your unit tests only test your code and do not depend on any particular behavior of the Android platform. If you want specific behavior you can use a mocking framework to replace these call.

3.2. Location of unit tests

As described in Android project organization for tests the unit tests of an Android project should be located in the app/src/test folder. See Test folder creation in Android Studio for the creation of such a test folder.

3.3. Required dependencies in the Gradle build file

To use JUnit tests for your Android application you need to add the dependency to JUnit and you other test dependencies to your Gradle build file.

dependencies {
    // Unit testing dependencies
    testCompile 'junit:junit:4.12'
    // Set this dependency if you want to use the Hamcrest matcher library
    testCompile 'org.hamcrest:hamcrest-library:1.3'
    // more stuff, e.g., Mockito
}

3.4. Run the unit tests from Gradle

Run your unit tests with the gradlew test command.

3.5. Run the unit tests from Android Studio

To run a unit test right-click on your test class in the Project window and select Run.

Running Unit tests in Android Studio

3.6. Location of test reports

The rest reports are created in the app/build/reports/tests/debug/`directory. The `index.html gives an overview and links to the individual test pages.

3.7. Activating default return values for mocked methods in android.jar

You can also instruct the Gradle build system to return default values for method calls in the `android.jar`with the following configuration in your Gradle build file.

android {
  // ...
  testOptions {
    unitTests.returnDefaultValues = true
  }
}

4. Exercise preparation: Create Android project to test project

Create the Android project as described in Android temperature converter.

5. Exercise: Create unit test for your Android project

5.1. Target of this exercise

In this exercise you learn how to create a simple JUnit4 test for an Android project.

5.2. Add JUnit dependency

Ensure you have the dependency to Junit in your app/build.gradle file. If the test folder structure is missing in your project, follow the process described in Test folder creation in Android Studio to create it.

dependencies {
        // Unit testing dependencies
        testCompile 'junit:junit:4.12'
}

5.3. Create test

In your app/src/test directory create the following two test methods for the ConverterUtil class.

package com.vogella.android.temperature.test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.vogella.android.temperature.ConverterUtil;

public class ConverterUtilTest {

        @Test
        public void testConvertFahrenheitToCelsius() {
                float actual = ConverterUtil.convertCelsiusToFahrenheit(100);
                // expected value is 212
                float expected = 212;
                // use this method because float is not precise
                assertEquals("Conversion from celsius to fahrenheit failed", expected,
                                actual, 0.001);
        }

        @Test
        public void testConvertCelsiusToFahrenheit() {
                float actual = ConverterUtil.convertFahrenheitToCelsius(212);
                // expected value is 100
                float expected = 100;
                // use this method because float is not precise
                assertEquals("Conversion from celsius to fahrenheit failed", expected,
                                actual, 0.001);
        }

}

5.4. Run unit tests

Ensure your unit tests are correctly implemented by running test tests. They should run successfully.

6. Instrumentation - The underlying Android testing API

6.1. Instrumentation

The Android testing API provides hooks into the Android component and application life cycle. These hooks are called the instrumentation API and allow your tests to control the life cycle and user interaction events.

Under normal circumstances your application cannot control the life cycle events and the user drives the application. For example, if Android creates your activity the onCreate() method is called. Or if the user presses a button your corresponding code is called. Via instrumentation you can control these events via your software tests.

6.2. Instrumentation tests

Instrumented unit tests are unit tests that run on Android devices and emulators instead of running on the Java virtual machine. These tests have access to the real device and its resources and are useful to unit test functionality which cannot be easily mocked by mocking frameworks. Also developer uses these tests if the framework functionality must be used to validate a functionality. An example is a test which validates a Parelable implementation.

Mockito as mocking framework can still be used to mock the parts of the Android system which are not interesting for the test.

An instrumentation-based test class allows you to send key events (or touch events) to the application under test.

For example, your instrumentation test can start the activity. Afterwards, it can call the finish() and restart the activity to test if the instance state of the activitiy is correctly restored.

With user interface testing framework like Espresso, the developer rarely has to use the instrumentation API directly.

6.3. How the Android system executes tests

The InstrumentationTestRunner is the base test runner for Android tests. This test runner starts and loads the test methods. Via the instrumentation API it communicates with the Android system. If you start a test for an Android application, the Android system kills any process of the application under test and then loads a new instance. It does not start the application, this is the responsibility of the test methods. The test method controls the life cycle of the components of the application.

The test runner also calls the onCreate() method of the application and activity under test during its initialization.

6.4. Location of instrumentation tests

As described in Android project organization for tests the unit tests of an Android project should be located in the app/src/androidTest/java folder. See Test folder creation in Android Studio for the creation of such a test folder.

6.5. Define dependencies and testInstrumentationRunner in the Gradle build file

To use JUnit tests for your Android application you need to add the dependency to JUnit and you other test dependencies to your Gradle build file. You needs also to specify the default testInstrumentationRunner runner as android.support.test.runner.AndroidJUnitRunner.

defaultConfig {
       ..... more stuff
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

dependencies {
    // Unit testing dependencies
    androidTestCompile 'junit:junit:4.12'
    // Set this dependency if you want to use the Hamcrest matcher library
    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
    // more stuff, e.g., Mockito
}

6.6. Using the @RunWith(AndroidJUnit4.class)

It is also recommended annotating the test with the @RunWith(AndroidJUnit4.class) annotation. AndroidJUnit4 extends JUnit4, so if you use pure Junit4 syntax and ActivityTestRule it is not required. But you need it, if you want to run, i.e., Espresso tests with ActivityTestRule and JUnit4.

6.7. Run the unit tests from Gradle

Run your unit tests with the gradlew connectedCheck command.

6.8. Run the unit tests from Android Studio

Right-click on your test class in the Project window and select Run.

6.9. Location of test reports

The test reports are created in the app/build/reports/androidTests/connected/ directory. The index.html gives an overview and links to the individual test pages.

6.10. How to replace the application for instrumentation tests

You can replace the application class for the instrumentation tests by overriding the AndroidJUnitRunner and its AndroidJUnitRunner method.

package com.vogella.android.daggerjunitmockito;

import android.app.Application;


public class MyMockApplication extends Application {

    @Override
    public void onCreate() {
       // do something important for your tests here
    }
}

Test runner

package com.vogella.android.daggerjunitmockito;

import android.app.Application;
import android.content.Context;
import android.support.test.runner.AndroidJUnitRunner;

public class MockTestRunner extends AndroidJUnitRunner {
  @Override
  public Application newApplication(ClassLoader cl, String className, Context context)
      throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return super.newApplication(cl, MyMockApplication.class.getName(), context);
  }
}

And you need to register this test runner in your build.gradle file.

android {
    /// more
        testInstrumentationRunner "com.vogella.android.daggerjunitmockito.MockTestRunner"
    }
    /// more
}

7. Mocking objects in Android

For you unit tests you can use mocking a framework to mock Android objects. This works also for tests running the a Android runtime. The Android framework provided in the past specialized mocking classes but these are not necessary anymore.

8. Exercise: Mocking file access

8.1. Target of this exercise

It is not required to use this class in your Android application, as it has only be provided to demonstrate the usage of Mockito for a unit test.

8.2. Create class to test

In an existing or in a new Android application with the package com.vogella.android.testing.mockitocontextmock add the following class.

public class Util {
        public static void writeConfiguration(Context ctx ) {
                try (FileOutputStream openFileOutput =
                         ctx.openFileOutput( "config.txt", Context.MODE_PRIVATE);) {

                        openFileOutput.write("This is a test1.".getBytes());
                        openFileOutput.write("This is a test2.".getBytes());
                } catch (Exception e) {
                        // not handled
                }
        }
}

8.3. Create a new unit test

Using Mockito the mocking framework, write a unit test which validates that: * openFileOutput is called exactly once * the write() method is called at least twice.

package com.vogella.android.testing.mockitocontextmock;

import android.content.Context;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.FileOutputStream;

import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TextContextOutputStream {

@Mock
Context context;

@Mock
FileOutputStream fileOutputStream;

@Before
public void init(){
    MockitoAnnotations.initMocks(this);
}

    @Test
public void writeShouldWriteTwiceToFileSystem() {
    try {
        when(context.openFileOutput(anyString(), anyInt())).thenReturn(fileOutputStream);
        Util.writeConfiguration(context);
        verify(context, times(1)).openFileOutput(anyString(), anyInt());
        verify(fileOutputStream, atLeast(2)).write(any(byte[].class));

    } catch (Exception e) {
        e.printStackTrace();
        fail();
    }
}
}

9. Android Testing Support Library

The Android Testing Support Library provides functionality to create and run Android tests. The library contains the AndroidJUnitRunner, the Espresso test framework and the UI Automator.

AndroidJUnitRunner allows to create and run JUnit 4 tests, while the Espresso test framework can be used to test the User Interface of your application. UI Automator allows to write cross application functional tests.

AndroidJunitRunner provides access to the instrumentation API, via the InstrumentationRegistery.

  • InstrumentationRegistry.getInstrumentation(), returns the Instrumentation currently running.

  • InstrumentationRegistry.getContext(), returns the Context of this Instrumentation’s package.

  • InstrumentationRegistry.getTargetContext(), returns the application Context of the target application.

  • InstrumentationRegistry.getArguments(), returns a copy of arguments Bundle that was passed to this Instrumentation. This is useful when you want to access the command line arguments passed to Instrumentation for your test.

It also gives access to the life cycle via the ActivityLifecycleMonitorRegistry.

10. Activity testing

11. More on Android testing

11.1. Android additional assertion

The Android testing API provides the MoreAsserts and ViewAsserts classes in addition to the standard JUnit Assert class.

11.2. Test groups

The @SmallTest, `@MediumTest`and `@LargeTest`annotations allows to classify tests.

This allows you to run, for example, only tests which do not run very long. Long running tests could than run only in the continuous integration server.

To run only selected tests you can configure the InstrumentationTestRunner via your Gradle plug-in. The following listing is an example for your build.gradle file to run only the tests annotated with @SmallTests.

android {
  //....
  defaultConfig {
  //....
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    testInstrumentationRunnerArgument "size", "small"
  }
}
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;

import org.junit.Test;

public class ExampleTest {

    @Test
    @SmallTest
    public void validateSecondActivity() {
        // Do something not so long...
    }

    @Test
    @MediumTest
    public void validateSecondActivityAgain() {
        // Do something which takes more time....
    }

}

11.3. Test filtering

You can annotate tests with annotations. The Android test runner allows to filter these tests.

Table 1. Annotations for filtering tests
Annotation Description

@RequiresDevice

Specifies that the test should run only on physical devices, not on emulators.

@SdkSupress

@SDKSupress(minSdkVersion=18)

11.4. Flaky tests

Actions in Android are sometimes time dependent. To tell Android to repeat a test once it fails, use the @FlakyTest annotation. Via the tolerance attribute of this annotation you can define how often the Android test framework should try to repeat a test before marking it as failed.

12. Exercise: Life cycle test

12.1. Target of this exercise

In this exercise the instrumentation test framework is demonstrated. For such test you would typically use higher level frameworks, like Espresso.

12.2. Create project which is tested

Create a new Android project called com.vogella.android.test.simpleactivity with the activity called MainActivity.

Add a second activity called SecondActivity to your project. This activity should use a layout with at least one TextView. The id of the TextView should be "resultText" and its text should be set to "Started".

Add an EditText field to the layout of the MainActivity class.

Add a button to the layout used by your MainActivity activity. If this button is clicked, the second activity should be started.

Put the text EditText field as extra into the intent using "text" as key. Also put the "http://www.vogella.com" String as extra into the intent and use the key "URL" for this.

Here is some example code for the MainActivity.

package testing.android.vogella.com.simpleactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

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

    public void onClick(View view) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("URL", "http://www.vogella.com");
        startActivity(intent);
    }
}

12.3. Create test project and class

Create a new instrumentation test similar to the following.

package com.vogella.android.test.simpleactivity.test;

import android.app.Activity;
import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.test.UiThreadTest;
import android.test.ViewAsserts;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.vogella.android.test.simpleactivity.R;

import com.vogella.android.test.simpleactivity.MainActivity;
import com.vogella.android.test.simpleactivity.SecondActivity;

public class SecondActivityFunctionalTest extends
                ActivityInstrumentationTestCase2<SecondActivity> {

        private static final String NEW_TEXT = "new text";

        public SecondActivityFunctionalTest() {
                super(SecondActivity.class);
        }

        public void testSetText() throws Exception {

                SecondActivity activity = getActivity();

                // search for the textView
                final TextView textView = (TextView) activity
                                .findViewById(R.id.resultText);

                // set text
                getActivity().runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                                textView.setText(NEW_TEXT);
                        }
                });

                getInstrumentation().waitForIdleSync();
                assertEquals("Text incorrect", NEW_TEXT, textView.getText().toString());

        }

        @UiThreadTest
        public void testSetTextWithAnnotation() throws Exception {

                SecondActivity activity = getActivity();

                // search for the textView
                final TextView textView = (TextView) activity
                                .findViewById(R.id.resultText);

                textView.setText(NEW_TEXT);
                assertEquals("Text incorrect", NEW_TEXT, textView.getText().toString());

        }

}

13. Using the Monkey tool for creating a random event stream

13.1. What is monkey?

Monkey is a command line tool which sends pseudo random events to your device. You can restrict Monkey to run only for a certain package and therefore instruct Monkey to test only your application.

13.2. How to use Monkey

The following commands sends 2000 random events to the application with the de.vogella.android.test.target package.

adb shell monkey -p de.vogella.android.test.target -v 2000

Monkey sometimes causes problems with the adb server. Use the following commands to restart the adb server.

adb kill-server
adb start-server

You can use the -s [seed] parameter to ensure that the generated sequence of events is always the same.

For more info on Monkey please see the Monkey description.

14. Application testing

The application class contains the logic, data and settings which are relevant for the whole application. Therefore you should test this object, to ensure it works correctly.

You can write JUnit 4 for the application object and test it on the JVM. In this case you would mock all dependencies to the application object. To test an Android application object on the Android runtime you use the ApplicationTestCase class. It is expected that Google will soon provide a special JUnit4 rule for testing the application object but at the moment his is not yet available.

The test runner of the Android tests (InstrumentationTestRunner) creates automatically an instance of application during its initialization phase. If you do asynchronous processing in your onCreate method you should consider that.

15. Exercise: Testing the Android application

15.1. Create project

Create a new Android application with the com.vogella.android.testing.applicationtest package name based on the Blank Activity template.

Add the following application object to your application.

package com.vogella.android.testing.applicationtest;

import android.app.Application;

import java.util.ArrayList;
import java.util.List;

public class MyApplication extends Application {
    public static final List<String> list = new ArrayList<String>();
}

Also declare the application it in your manifest file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.vogella.android.testing.applicationtest" >

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

15.2. Create unit test for application object

In your app/src/test`directory create a new unit test and assert that the `MyApplication.list field is not empty and has initially a size of zero.

15.3. Create instrumented test for application object

Create the following unit test based on the JUnit 3 testing framework.

package com.vogella.android.testing.applicationtest;

import android.content.pm.PackageInfo;
import android.test.ApplicationTestCase;
import android.test.MoreAsserts;

public class ApplicationTest extends ApplicationTestCase<MyApplication> {

    private MyApplication application;

    public ApplicationTest() {
        super(MyApplication.class);
    }

    protected void setUp() throws Exception {
        super.setUp();
        createApplication();
        application = getApplication();

    }

    public void testCorrectVersion() throws Exception {
        PackageInfo info = application.getPackageManager().getPackageInfo(application.getPackageName(), 0);
        assertNotNull(info);
        MoreAsserts.assertMatchesRegex("\\d\\.\\d", info.versionName);
    }

}

16. Testing other components

16.1. Service testing

To test a service you use the ServiceTestRule class from the Android Testing Support Library. The old ServiceTestCase is deprecated.

This rule provides a simplified mechanism to start and shutdown your service before and after your test. It guarantees that the service is successfully connected when starting (or binding to) a service. The service can be started (or bound) using one of the helper methods. It will automatically be stopped (or unbound) after the test completes and any methods annotated with @After are finished.

This rule doesn’t support IntentService because it’s automatically destroyed after the onHandleIntent method.

The following listing is an example of testing a service.

@RunWith(AndroidJUnit4.class)
@MediumTest
public class MyServiceTest {

    @Rule
    public final ServiceTestRule mServiceRule = new ServiceTestRule();

    // test for a service which is started with startService
    @Test
    public void testWithStartedService() {
        mServiceRule.
        startService(new Intent(InstrumentationRegistry.getTargetContext(),
                        MyService.class));
        // test code
    }

    @Test
 // test for a service which is started with bindService
    public void testWithBoundService() {
        IBinder binder = mServiceRule.
                        bindService(new Intent(InstrumentationRegistry.getTargetContext(),
                                        MyService.class));
        MyService service = ((MyService.LocalBinder) binder).getService();
        assertTrue("True wasn't returned", service.doSomethingToReturnTrue());
    }
}
adb kill-server
adb start-server

16.2. Content provider testing

To test a content provider, you use the ProviderTestCase2 class. ProviderTestCase2 automatically instantiates the provider under test and inserts an IsolatedContext object. This context is isolated from the Android system, but still allows file and database access. The usage of the IsolatedContext object ensures that your provider test does not affect the real device.

ProviderTestCase2 also provides access to a MockContentResolver via the getMockContentResolver() method.

You should test all operations of the provider and also what happens if the provider is called with an invalid URI or with an invalid projection.

16.3. Loader testing

To test a loader, you use the `LoaderTestCase`class. It is expected that a JUnit 4 rule will be provided in the future to replace this class.

17. Support annotations

Google provides a new annotations package. This package includes a number of metadata annotations, which you can use in your code, to prevent bugs.

To use these annotations add the following dependency to your Gradle build file.

dependencies {
    compile 'com.android.support:support-annotations:22.2.0'
}

The following information describes the most important annotations. See http://tools.android.com/tech-docs/support-annotations for more information.

17.1. Nullness Annotations

The @Nullable annotation can be used to indicate that a given parameter or return value can be null. Similarly, the @NonNull annotation can be used to indicate that a given parameter (or return value) can not be null.

17.2. Threading Annotations: @UiThread, @WorkerThread, …​

If a method can only be called from a specific type of thread, you can annotate it with one of the following annotations:

  • @UiThread

  • @MainThread

  • @WorkerThread

  • @BinderThread

Example:

@WorkerThread
protected abstract Result doInBackground(Params... params);

@MainThread
  protected void onProgressUpdate(Progress... values) {
  }

18. Creating code coverage report

A code coverage report shows you how much of your application code is covered by tests. To create such a report, you can create a separate launch configuration. For this, select your package package and select menu:[Create Tests in…​].

android code coverage10

You can now create a runtime configuration for the code coverage. If you run it a report is generated.

android code coverage20
android code coverage30
android code coverage40

19. Test folder creation in Android Studio

The recent versions of Android Studio has added a test folder to its default project template. In case you using a template which does not create a test folder, you have to create it manually. To create the test folder in Android Studio, switch to the Project view, this shows you the directory structure of your project.

Switching to the Project view in Android Studio

Select the src and use the context menu to create a new test folder.

Switching to the Project view in Android Studio
Adding a java folder
Adding a java folder

If not yet done, also add the JUnit dependency to your Gradle build file.

dependencies {
    // Unit testing dependencies
    testCompile 'junit:junit:4.12'
    // Set this dependency if you want to use the Hamcrest matcher library
    testCompile 'org.hamcrest:hamcrest-library:1.3'
    // more stuff, e.g., Mockito
}

The creation of the Java folder might add the new test directory as source file to your build.gradle file. If you have the following entry in your app/build.gradle file you need to REMOVE it. test should NOT be treated as normale source folder.

 sourceSets { main { java.srcDirs = ['src/main/java', 'src/test/java/'] } }

Afterwards you can add your unit test to this folder structure.

20. About this website

21. Android testing resources

https://github.com/googlesamples/android-testing - Android testing examples from Google]

https://github.com/googlesamples/android-testing-templates - Android testing template project from Google

http://tools.android.com/tech-docs/unit-testing-support - Unit test support description from Google

http://www.vogella.com/tutorials/Robolectric/article.html - Using Robolectric for Android unit testing on the JVM

http://www.vogella.com/tutorials/AndroidTestingEspresso/article.html - Android user interface testing with Espresso

http://blog.sqisland.com/2015/12/mock-application-in-espresso.html Chiu-Ki Chan about Mock Application in Espresso for Dependency Injection

https://artemzin.com/blog/how-to-mock-dependencies-in-unit-integration-and-functional-tests-dagger-robolectric-instrumentation/ Artem Zinnatullin blog post on How to mock dependencies in Unit, Integration and Functional tests; Dagger, Robolectric and Instrumentation

21.1. vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.

The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.

Copyright © 2012-2016 vogella GmbH. Free use of the software examples is granted under the terms of the EPL License. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.