Unit testing in Android

Unit testing in Android

For any software development testing is an important phase where one has to check the stability and reliability of the software.

Testing can be done in two different ways:

Manual testing:

Time consuming and tedious: Since test cases are executed by human, it is very slow and tedious.

Huge resources required: More testers are required to list all test cases and executed manually.

Less reliable: Manual testing is less reliable as tests may not be performed with precision each time because of human errors.

No programming required.

Automated testing:

Less time consuming: Significantly faster than human resources.

Fewer resources required: Test cases are executed by using an automation tool so less testers are required in automation testing.

More reliable: Tests perform exactly same operation each and every time they are run.

Required programming.

Automated testing has two type of testing:

  • Unit testing
  • UI testing

In this article we will explore about unit testing in detail. How to configure in Android project for unit testing and how to run unit testing. So, let’s begin.

What is Unit testing?

Unit testing is used to test each of the smallest testable parts (units) individually and independently. By using unit tests, each part is verifying the logic. This way we can guarantee that our parts work properly for the set of inputs that we expect. The dependencies can be mocked, which will enable us to write tests that execute fast.

The goal of Android unit testing is to isolate each part of the program and show that the individual parts are correct. A unit test provides a strict, written contract that the piece of code must satisfy. As a result, it affords several benefits.

Android unit testing

Android unit testing

Local tests which are tests that are performed using JVM only. They are meant for testing business logic that is not interacting with the operating system thus takes less time to test.

Instrumented tests are tests which are used for testing logic. They communicate with operating system thus they are performed on real/physical device/emulator, so it takes more time compared to local tests.

There are 2 categories of tests. Choose the relevant one based on the goals of the logic. Of course, it is better to write local tests, if it’s possible. Also, when creating tests, pay close attention to package organization. The following structure is called package organization:

  • app/src/main/java — app source code.
  • app/src/test/java — local tests.
  • app/src/androidTest/java — instrumented tests.

Which part is testable or which part is not testable?

For many people the more common question is which areas/functions to test. In my viewpoint it is better to define.

Which part is not testable?

– Other framework libraries (you should assume they work correctly, because they should have their own tests).

– The database (you should assume it works correctly when it is available).

– Trivial code (like getters and setters).

– Code that has non-deterministic results (Think Thread order or random numbers).

Which part is testable?

– Business logic.

– Everything that contains conditions.

Let’s start with the local unit tests as they are easy to set-up.

Start by adding a dependency on JUnit in your project. The dependency is of type `testCompile` which means that the dependencies are only required to compile the test source of the project. By default it also includes the compiled production classes and the compiled time dependencies.

dependencies {

testCompile “junit:junit:4.12”

}

JUnit has below defined methods to test.

void assertEquals(expected, actual) – Check that two primitives/objects are equal.

void assertTrue(condition) – Check that a condition is true.

void assertFalse(condition) – Check that a condition is false.

void assertNotNull(object) – Check that an object isn’t null.

void assertNull(object) – Check that an object is null.

void assertSame(expected, actual) – The assertSame() method tests if two object references point to the same object.

void assertNotSame(unexpected, actual) – The assertNotSame() method tests if two object references do not point to the same object.

Void assertArrayEquals(expectedArray, actualArray) – The assertArrayEquals() method will test whether two arrays are equal to each other.

Below is a simple example of using assertEquals.

public int plus(int firstValue, int secondValue) {

return firstValue + secondValue;

}

Below is test for this method.

@Test

public void plusOperationTest() {

assertEquals(4, plus(2, 2));

}

As you can see assertEquals method has two parameters. The first parameter has expected value and the second parameter has an actual value from method which summarizes the two number values. As you can see in above test method 2 and 2 argument of plus method and expecting to get result 4.

It’s really a simple test.

Annotations

Annotations are like meta-tags that you can add to your code and apply them to methods, variables, classes etc.

@Test

The @Test annotation tells JUnit that the public void method to which it is attached can be run as a test case.

@Before

Several tests need similar objects created before they can run. Annotating a public void method with @Before let’s JUnit know that this method to be run before each Test method.

@After

If you allocate some external resources in a @Before method you need to release them after the test runs. Annotating a public void method with @After allows to do it.

@BeforeClass

Annotating a public static void method with @BeforeClass allows to be run once before any of the test methods in the class.

@AfterClass

This will perform the method after all tests have finished. This can be used to perform clean-up some activities.

 @Ignore

The @Ignore annotation is used to ignore the test and that test will not be executed.

Below are lists of libraries which can be used with Junit tests.

Mockito

Mockito is a framework that enables us to write clean tests in Java using mocking the classes. It simplifies the process of creating test doubles (mocks), which are used to replace the original dependencies of a component/module used in production.

To add Mockito to your test dependencies, update your dependencies as follows

dependencies {

// Required — JUnit 4 framework

testCompile ‘junit:junit:4.12’

// Mockito framework

testCompile ‘org.mockito:mockito-core:1.10.19’

}

Robolectric

Robolectric is an Android unit testing framework which allows you to run tests inside the JVM on your project. Robolectric rewrites android sdk classes as they’re being loaded and makes it possible for them to run on a JVM, resulting in fast test. It also handles inflate views, loading resource and other stuff which implemented in native C code on Android devices. Now making the need for emulators/physical devices to run automated tests obsolete.

To add Robolectric to your test dependencies, update your dependencies as follows

dependencies {

compile fileTree(dir: ‘libs’, include: [‘*.jar’])

// Add Junit and mockito as testing dependencies

testCompile ‘junit:junit:4.12’

testCompile ‘org.mockito:mockito-core:1.10.19’

//For Robolectric

testCompile “org.robolectric:robolectric:3.0”

}

Conclusion

This article contains understanding of unit tests for Android code. Depending upon your need for the project you can have one or many types of above tests in your project. Automated unit tests have a lot of long-term benefits. It should be thought and estimated as part of your development effort itself. The above-described frameworks help to write