Guide to Testing in Android (Part 1): Unit Testing with JUnit

Shalen MathewShalen Mathew
6 min read

Testing is often underrated in Android development. While it might feel boring or unnecessary for small or personal projects, it becomes essential when building production-ready apps. In real-world scenarios, where multiple developers work on the same codebase, testing ensures your code works as intended, prevents regressions, and catches potential issues early.

Learning testing can set you apart in the job market, especially in large organizations where strong testing skills add real value and strengthen your resume.

This is part one of a blog series on testing that I’ll be publishing soon. We’ll begin with Unit testing…will try to keep the blog short , I don’t want to test your patience 😉

Lets start with … What is Unit Testing ?

Unit testing is the process of testing individual pieces of code, like functions or classes to ensure they work correctly on their own.

Then … What is Junit ?

JUnit is a testing framework for Java and Kotlin that helps developers write and run unit tests, ensuring that individual parts of their code work as expected.

Lets write a simple unit test for better understanding

class Helper {

    fun isPalindrome(input: String): Boolean {
        var i = 0
        var j = input.length - 1
        var result = true

        while (i < j) {
            if (input[i] != input[j]) {
                result = false
                    break
            }
            i++
            j--
        }
        return result
    }

}

Here we going to test this simple Palindrome function ( assuming you already know what a palindrome is — if not, feel free to look it up to better understand the logic )

so we going to test this logic… The whole point of unit testing is to make sure our logic behaves as we intended.

As you may know, a palindrome is a word that reads the same forwards and backwards. Since we already know this truth about our logic , we'll write a test to ensure our logic act that way.

So lets write our first test …

  1. This is how our code look in our IDE

  2. Go to your fun or the class your function in right click on it ,this will open a dialog box like this which you are already familiar with …Go to the Generate section and click on it

  1. By clicking on Generate it will open a new dialog box click Test in there, as you can see in the image

  1. This will create another dialog box where you need to make 2 changes

    i. keep Testing Library : JUnit4

    ii. click the checkbox as shown in the image below

  1. This will open another dialog box , make sure you have selected unitTest folder, that where all your test related to unit test will go

  1. This will create a class named HelperTest in the package com.packagname.yourapplicationname(test) as can see in the image.

All the code related to testing will go in there ….

So we are all set to write our first test case…

While writing our unit test , it's helpful to structure your code in a clear, consistent way. One common approach is the Arrange, Act, Assert (AAA) pattern, which organizes your test into three distinct phases:

  1. Arrange: Set up the necessary objects and conditions for the test.

  2. Act: Perform the action or invoke the method you want to test.

  3. Assert: Check if the outcome is as expected.

First we will Arrange all the necessary objects required for our testing :

As you know, the function we want to test is in the Helper class, so we need an instance of this class to access the function. To do this, we’ll initialize the object in a special method annotated with @Before. This annotation ensures that the method runs before each test is executed, setting up any necessary conditions for the tests.

class HelperTest {

   private lateinit var helper: Helper

    @Before
    fun setUp(){
         // ARRANGE
        // This function runs before each test case.
        // It's useful for initializing objects and avoiding repeated setup code.
        helper=Helper()
    }

}

Now we will test our Palindrome’s logic in a function annotated with @Test

class HelperTest {

   private lateinit var helper: Helper

    @Before
    fun setUp(){
        // This function runs before each test case.
        // It's useful for initializing objects and avoiding repeated setup code.
        helper=Helper()
    }

    @Test
    fun isPalindrome() {

    }
}

Now we will test our logic inside the above empty function

We'll call the isPalindrome function from the Helper class—this is the Act phase where we get the result.
Then, we'll check if the result matches our expected outcome

The whole point of testing is to pass known inputs to a function and check if it returns the expected result.
When you already know how the function should behave with specific parameters, you can use that knowledge to confirm it's working correctly.

For example, I know for sure that if I pass "level" to the isPalindrome function, it should return true because "level" is a palindrome.
Since I already know the expected result, I can use this to verify the function's behavior.
If the actual result is different from what I expect, it means there's likely something wrong with the logic.

class HelperTest {

   private lateinit var helper: Helper

    @Before
    fun setUp(){
        // This function runs before each test case.
        // It's useful for initializing objects and avoiding repeated setup code.
        helper=Helper()
    }

    @Test
    fun isPalindrome() {
        // Act
        val result = helper.isPalindrome("level")
    }
}

In the above code as you can see we are calling our function and storing the returned result in a variable named result

Now we need to verify that the returned result matches the expected output—this is the Assert phase.

We’ll do this using the assertEquals() function, which takes two parameters: expected result and actual result.
If both values match, it means our logic is working as intended.

class HelperTest {

   private lateinit var helper: Helper

    @Before
    fun setUp(){
        // This function runs before each test case.
        // It's useful for initializing objects and avoiding repeated setup code.
        helper=Helper()
    }

    @Test
    fun isPalindrome() {
        // Act
        val result = helper.isPalindrome("level")

      //Assert
     // assertEquals(expected, actual)
        assertEquals(true,result)

    }
}

now if you run your test case it will show all test passed like this below image

And with that, we’ve successfully written our first test case!
Hopefully, this article gave you a basic understanding of how unit testing works in Android using JUnit.

Here are some questions you can solve to improve your understanding of unit testing.

  1. Write a unit test for a password validation function.
    The function should return true only if the following conditions are met:

    • The password is not empty

    • The length is greater than 6 and less than 15

If all conditions are satisfied, the function should return true; otherwise, it should return false.

  1. Write a function to reverse a string without using any library functions.

That’s all from me for today 😁. If I am lacking somewhere or this article needs some correction just comment down. Byeeee!!!👋

Follow me on socials :
X , LinkedIn , Github, Butterfly , Linktree

0
Subscribe to my newsletter

Read articles from Shalen Mathew directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Shalen Mathew
Shalen Mathew

I write about Android dev & Open Source