Difference between Android Instrumentation test and Unit test in Android Studio?

AndroidUnit TestingTestingAndroid StudioIntegration Testing

Android Problem Overview


As of Android Studio 1.1rc there's Unit testing support and I'm wondering what's the difference between Android Instrumentation Tests and Unit tests.

As I understand it:
Unit tests are useful for testing code which doesn't call the Android API, and the Android instrumentation tests are rather integration tests to test Android API specific elements or GUI components.

However if you use a framework like Robolectric or Mockito in your unit tests, you can test Android code (without the need of a device) if I'm not mistaken.


Is this correct, or is there a bigger difference? If so, what's the use of each?

Android Solutions


Solution 1 - Android

It seems to me that instrumentation testing is integration testing with the ability to control the life cycle and the events (onStart, onCreate etc) of the app.

Unit testing, as i understand it, is testing a Unit (eg Class) for its data and behavior.

For example, say you have a game: this game runs on an activity (main activity) and you have a character based on a Robot class, that has 2 methods (fire and move). You would test the main activity with an instrumentation test to see if it saves correctly when you leave the app, if it restores correctly when you restore it etc. and you would test Robot with a Unit test, to test its attributes and behavior.

Disclaimer: I'm not a java person, but i took interest in your question and i answered it based on a minor search online. You probably have to dig deeper into this to find a more detailed answer.

Solution 2 - Android

Unit tests isolate the component under test, and this is the reason why are often used together with Mocks frameworks as Mockito:because isolate the unit from their dependencies. Please notice what you say regarding the Android API is partially true, because there are also Instrumented Unit tests, namely Instrumentation is part of the Junit package as well, and also the classes that extend TestCase as the class AndroidTestCase is part of the Junit package but allows the use of A)Context, that you can call with getContext(), and B)Resources that are part of the Android API! Also please consider AndroidTestCase is a base class and there are several other classes quite useful that extend this class. They test specifically Loaders, ContentProviders and even Services and also them have access to the Android API. so these classes provide JUnit testing framework as well as Android-specific methods. Now with Junit4 there is the ServiceTestRule that extends directly from Object and allow you easier to test a Service, although you cannot start an Intent directly inside this class.

Instrumentation tests they are also into the Junit package, but the control of the Android API is quite total because Instrumentation Tests are instantiated in the system before any application code is run, and to test you need to open the real application(emulator or a phone connected with USB). They access to android components(ex. click a button) and application life cycle, they are usually slower than Junit tests that extend TestCase( the ones examined above) the typical use is with ActivityInstrumentationTestCase2 that has a functional test approach, more user oriented.

EDIT: Regarding Roboelectric and Mockito, that are togheter with Espresso between the most popular testing frameworks at the moment(13 July 2016), Roboelectric allows you to run multiple tests in seconds instead of minutes, and this comes really handy in teams that have to run continuous tests, and are subject to continuous integration.

From the site of Robolectric:

> An alternate approach to Robolectric is to use mock frameworks such as > Mockito or to mock out the Android SDK. While this is a valid > approach, it often yields tests that are essentially reverse > implementations of the application code. > Roboelectric allows a test style that is closer to black box testing, > making the tests more effective for refactoring and allowing the tests > to focus on the behavior of the application instead of the > implementation of Android. You can still use a mocking framework along > with Robolectric if you like.

Mockito that also can be used with Junit, is really used with the exception of when have to manage final classes, anonymous classes or primitive types.

Solution 3 - Android

UNIT TESTING

> Unit tests that run on your local machine only. These tests are > compiled to run locally on the JVM to minimize execution time. Use > this approach to run unit tests that have no dependencies on the > Android framework or have dependencies that mock objects can satisfy.

So basically, you run plain java code to test for example a content provider, database connections, input and output of methods. This doesn't run on Android. To run it you DON'T need a device.

INSTRUMENTATION TESTING

> Unit tests that run on an Android device or emulator. These tests have > access to Instrumentation information, such as the Context of the app > under test. Use this approach to run unit tests that have Android > dependencies which mock objects cannot easily satisfy.

So it mocks how the user will use the actual application, therefore you NEED a device (physical or emulator) to run it. It has access to views, activities, context, etc.

Reference: http://developer.android.com/tools/testing/testing_android.html

Solution 4 - Android

Android tests

[Test types]

The diagram of test types in Android world https://i.stack.imgur.com/bY7f4.png" height="300">

Local Unit test: JUnit, Mockito, PowerMock
Instrumentation tests(a kind of functional tests): Espresso, Robolectric, Robotium

//Functional tests(Integration, UI)
src/androidTest/java

//Unit tests
src/test/java

[Run test via Command line]

[Test double types]

Solution 5 - Android

Unit Testing:

Often Unit tests are referred to as “local tests” or “local unit tests”. The main reason for this seems to be that you want to be able to run tests without a device or an emulator attached.

Unit tests cannot test the UI for your app without mocking objects such as an Activity.


Instrumentation tests:

Instrumentation tests run on a device or an emulator. In the background, your app will be installed and then a testing app will also be installed which will control your app, launching it and running UI tests as needed.

Instrumentation tests can be used to test none UI logic as well. They are especially useful when you need to test code that has a dependency on a context.


Ref link for example

Solution 6 - Android

Unit Testing

It Runs on the local machine only.

Instrumentation Test case

It Runs on the android device or emulator .if you check the test case it runs on emulator or android device

Solution 7 - Android

Unit tests focus on small portions of code (i.e. class-level methods) and provide basic validation that code is working as expected. Espresso tests provide basic validation that the UI is working as expected.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoen93View Question on Stackoverflow
Solution 1 - AndroidgemantzuView Answer on Stackoverflow
Solution 2 - AndroidtrocchiettoView Answer on Stackoverflow
Solution 3 - AndroidIsaac UrbinaView Answer on Stackoverflow
Solution 4 - AndroidyoAlex5View Answer on Stackoverflow
Solution 5 - Androidakhilesh0707View Answer on Stackoverflow
Solution 6 - AndroidmathiView Answer on Stackoverflow
Solution 7 - AndroidBharat SonawaneView Answer on Stackoverflow