Paramclasses Academy - Blog

Tutorials Details

←
Post 35 of 40
→

How to Testing Android App: Unit Tests, UI Tests and Manual Testing ?

How to Testing Android App: Unit Tests, UI Tests and Manual Testing ?

November 4, 2026

1. Introduction

Testing is an important part of Android app development. Writing code is not enough; developers must also verify that the application works correctly under different conditions.

For example, consider a student registration application. We need to check:

  • Does the registration form accept valid information?

  • Does it reject empty fields?

  • Does the Save button work correctly?

  • Is the data stored correctly?

  • Does the application behave properly on different screen sizes?

Android Studio provides testing tools and frameworks that help developers find bugs before releasing an application.

In this tutorial, we will learn three important testing approaches:

  1. Manual Testing

  2. Unit Testing

  3. UI Testing

We will also build a small Java application and write automated tests for it.

2. What Is Software Testing?

Software testing is the process of checking whether an application behaves according to its requirements.

The main objectives are:

  • Find bugs and errors.

  • Verify application functionality.

  • Improve application reliability.

  • Check user interactions.

  • Prevent problems after code changes.

  • Improve the overall user experience.

Testing should be performed throughout development, not only before publishing an application.

3. Understanding Manual Testing

Manual Testing means checking an application by using it like a normal user.

A tester opens the application, enters information, clicks buttons, changes screens, and verifies the results.

Example: Student Registration App

Suppose we have a registration screen with:

  • Name field

  • Email field

  • Mobile number field

  • Register button

A tester can perform these checks:

Test Case 1: Valid Information

Enter a valid name, email, and mobile number. Click Register.

Expected Result: The application should accept the information and display a success message.

Test Case 2: Empty Name

Leave the name field empty and enter the remaining information.

Expected Result: The application should display a name validation message.

Test Case 3: Invalid Email

Enter an invalid email address.

Expected Result: The application should reject the invalid email.

Test Case 4: Empty Form

Leave all fields empty and click Register.

Expected Result: The application should ask the user to enter the required information.

Advantages of Manual Testing

  • Easy for beginners to understand.

  • No test code is required.

  • Useful for checking the complete user experience.

  • Helps identify visual and usability problems.

Limitations

  • Repeating the same tests takes time.

  • Results can depend on the tester.

  • Large applications require many test cases.

  • Some bugs are difficult to reproduce manually.

4. What Is Unit Testing?

Unit Testing means testing a small, individual part of your application independently.

A unit can be a method, class, or a small piece of business logic.

For example, suppose an application contains an addition method:

public int add(int a, int b) {
    return a + b;
}

We can test this method without opening the Android application.

If we provide:

a = 10
b = 20

The expected result is:

30

A unit test checks whether the actual result matches the expected result.

Why Is Unit Testing Important?

  • Finds logic errors early.

  • Tests individual methods independently.

  • Makes code changes safer.

  • Reduces repeated manual testing.

  • Helps developers maintain large applications.

5. Understanding JUnit in Android

JUnit is a testing framework commonly used to write and execute Java unit tests.

Android Studio projects commonly use JUnit 4 for local unit testing.

Important JUnit annotations include:

@Test: Identifies a method as a test method.

@Before: Runs before each test method.

@After: Runs after each test method.

@BeforeClass: Runs once before all test methods in a test class.

@AfterClass: Runs once after all test methods in a test class.

Common assertion methods include:

assertEquals(expected, actual);
assertTrue(condition);
assertFalse(condition);
assertNull(object);
assertNotNull(object);

Assertions compare the expected result with the actual result. If the assertion fails, the test is reported as failed.

6. Local Unit Tests vs Instrumented Tests

Android supports different test environments.

Local Unit Tests

Local unit tests run on your development machine using the local Java Virtual Machine (JVM).

They are generally used to test business logic that does not require a real Android device or Android framework behavior.

Default location:

app/src/test/java/

Examples:

  • Addition and subtraction methods.

  • Form validation logic.

  • Discount calculations.

  • Data conversion methods.

  • Simple business rules.

Instrumented Tests

Instrumented tests run on an Android emulator or physical Android device.

They have access to Android framework APIs and the application environment.

Default location:

app/src/androidTest/java/

Examples:

  • Checking Activity behavior.

  • Testing Android components.

  • Verifying database integration.

  • Automating user interactions.

  • Testing application behavior on a device.

Local tests are generally faster. Instrumented tests are useful when actual Android device or framework behavior needs to be tested.

7. What Is UI Testing?

UI Testing means checking whether the application's user interface behaves correctly when users interact with it.

For example:

  1. Open the application.

  2. Enter a name in an EditText.

  3. Click a Button.

  4. Verify that the expected message appears.

UI testing helps verify:

  • Buttons and click events.

  • Text fields and input.

  • Navigation between screens.

  • Displayed messages.

  • Screen behavior.

  • User interaction workflows.

What Is Espresso?

Espresso is an Android UI testing framework used to automate interactions with application views.

It provides methods for:

  • Finding UI elements.

  • Clicking buttons.

  • Entering text.

  • Checking displayed text.

  • Verifying whether a view is visible.

A simple Espresso test looks like this:

onView(withId(R.id.btnSubmit))
        .perform(click());

onView(withText("Success"))
        .check(matches(isDisplayed()));

This test clicks a button and checks whether the text "Success" is displayed.

8. Create a Practical Testing Project

Now we will create a simple Java application called AndroidTestingApp.

Our application will contain:

  • Two number input fields.

  • One Calculate button.

  • One result TextView.

We will test its calculation logic using JUnit and its user interface using Espresso.

Step 1: Create a New Android Project

  1. Open Android Studio.

  2. Create a new project.

  3. Select Empty Views Activity.

  4. Set the project name to AndroidTestingApp.

  5. Select Java as the programming language.

  6. Finish the project setup.

Step 2: Create a Calculator Utility Class

Create a Java class named Calculator.java.

package com.example.androidtestingapp;

public class Calculator {

    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }

    public int divide(int a, int b) {

        if (b == 0) {
            throw new IllegalArgumentException(
                    "Cannot divide by zero"
            );
        }

        return a / b;
    }
}

This class contains four methods:

  • add() adds two numbers.

  • subtract() subtracts two numbers.

  • multiply() multiplies two numbers.

  • divide() divides two numbers and prevents division by zero.

Keeping calculation logic in a separate class makes it easier to test independently.

Step 3: Create the XML Layout

Open res/layout/activity_main.xml and use this code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp">

    <EditText
        android:id="@+id/etFirstNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="First number"
        android:inputType="numberSigned" />

    <EditText
        android:id="@+id/etSecondNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Second number"
        android:inputType="numberSigned" />

    <Button
        android:id="@+id/btnCalculate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Calculate" />

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Result will appear here"
        android:textSize="20sp" />

</LinearLayout>

We have created two input fields, one button, and one TextView.

Step 4: Write MainActivity.java

Open MainActivity.java and add:

package com.example.androidtestingapp;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    EditText etFirstNumber, etSecondNumber;
    Button btnCalculate;
    TextView tvResult;

    Calculator calculator;

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

        etFirstNumber = findViewById(R.id.etFirstNumber);
        etSecondNumber = findViewById(R.id.etSecondNumber);
        btnCalculate = findViewById(R.id.btnCalculate);
        tvResult = findViewById(R.id.tvResult);

        calculator = new Calculator();

        btnCalculate.setOnClickListener(v -> {

            String firstInput = etFirstNumber
                    .getText().toString().trim();

            String secondInput = etSecondNumber
                    .getText().toString().trim();

            if (firstInput.isEmpty() || secondInput.isEmpty()) {

                Toast.makeText(
                        this,
                        "Enter both numbers",
                        Toast.LENGTH_SHORT
                ).show();

                return;
            }

            try {

                int first = Integer.parseInt(firstInput);
                int second = Integer.parseInt(secondInput);

                int result = calculator.add(first, second);

                tvResult.setText("Result: " + result);

            } catch (NumberFormatException e) {

                Toast.makeText(
                        this,
                        "Enter valid integer numbers",
                        Toast.LENGTH_SHORT
                ).show();
            }
        });
    }
}

This Activity reads the input fields, validates them, calls the Calculator class, and displays the result.

Replace the package declaration with the package name generated by your project.

9. Write Your First JUnit Test

Now we will test the calculation methods.

Open:

app/src/test/java/

Create a Java class named:

CalculatorTest.java

Add the following code:

package com.example.androidtestingapp;

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

import static org.junit.Assert.assertEquals;

public class CalculatorTest {

    Calculator calculator;

    @Before
    public void setUp() {
        calculator = new Calculator();
    }

    @Test
    public void testAddition() {

        int result = calculator.add(10, 20);

        assertEquals(30, result);
    }

    @Test
    public void testSubtraction() {

        int result = calculator.subtract(20, 10);

        assertEquals(10, result);
    }

    @Test
    public void testMultiplication() {

        int result = calculator.multiply(5, 4);

        assertEquals(20, result);
    }

    @Test
    public void testDivision() {

        int result = calculator.divide(20, 5);

        assertEquals(4, result);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testDivisionByZero() {

        calculator.divide(10, 0);
    }
}

Understanding This Test Code

@Before: Creates a fresh Calculator object before each test.

@Test: Marks a method as a test.

assertEquals(): Checks whether the actual result matches the expected result.

expected: Verifies that the specified exception is thrown by the test.

For example:

assertEquals(30, result);

Here:

  • Expected value = 30

  • Actual value = result

If both values match, the test passes.

10. Run the JUnit Tests in Android Studio

Follow these steps:

  1. Open CalculatorTest.java.

  2. Right-click inside the test class.

  3. Select Run 'CalculatorTest'.

  4. Wait for Gradle to finish executing the tests.

  5. Check the Run window for test results.

If all five tests pass, Android Studio will show a successful test result.

If a test fails, inspect the expected and actual values to find the problem.

11. Write an Espresso UI Test

Now we will test the actual application interface.

Step 1: Add Testing Dependencies

Open the app-level build.gradle file.

Add the following dependencies using versions compatible with your project's AndroidX Test setup:

dependencies {

    testImplementation 'junit:junit:4.13.2'

    androidTestImplementation 'androidx.test:runner:1.6.2'

    androidTestImplementation 'androidx.test:rules:1.6.1'

    androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
}

Add the test runner inside the android block:

android {
    defaultConfig {
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

Click Sync Now and wait for Gradle synchronization.

If your project uses Kotlin DSL (build.gradle.kts), use the equivalent dependency syntax instead.

Step 2: Create the UI Test Class

Open:

app/src/androidTest/java/

Create a Java class named:

CalculatorUITest.java

Add this code:

package com.example.androidtestingapp;

import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

@RunWith(AndroidJUnit4.class)
public class CalculatorUITest {

    @Rule
    public ActivityScenarioRule<MainActivity> activityRule =
            new ActivityScenarioRule<>(MainActivity.class);

    @Test
    public void testAdditionThroughUI() {

        onView(withId(R.id.etFirstNumber))
                .perform(replaceText("10"), closeSoftKeyboard());

        onView(withId(R.id.etSecondNumber))
                .perform(replaceText("20"), closeSoftKeyboard());

        onView(withId(R.id.btnCalculate))
                .perform(click());

        onView(withId(R.id.tvResult))
                .check(matches(isDisplayed()));

        onView(withId(R.id.tvResult))
                .check(matches(withText("Result: 30")));
    }
}

Understanding the Espresso Code

@RunWith(AndroidJUnit4.class): Uses the AndroidX test runner for this instrumented test.

ActivityScenarioRule: Launches the Activity before the test runs and manages its lifecycle.

onView(): Finds a View in the application.

withId(): Finds a View using its resource ID.

perform(): Performs an action on the selected View.

replaceText(): Enters text into an EditText.

click(): Clicks a button or another clickable View.

matches(): Checks whether a condition is true.

isDisplayed(): Checks whether a View is visible.

withText(): Checks the text displayed by a View.

Step 3: Run the UI Test

  1. Start an Android emulator or connect a physical device.

  2. Open CalculatorUITest.java.

  3. Right-click the test class.

  4. Select Run 'CalculatorUITest'.

  5. Wait for the application and test APK to launch.

  6. Android Studio will display the test result.

The test should enter 10 and 20, click Calculate, and verify that the result is 30.

12. What Is a Test Case?

A Test Case is a set of instructions used to verify a particular application feature.

A test case generally contains:

  • Test Case ID

  • Test Scenario

  • Input Data

  • Test Steps

  • Expected Result

  • Actual Result

  • Pass or Fail Status

Example:

Test Case ID: TC001

Test Scenario: Verify calculator addition.

Input Data: 10 and 20.

Test Steps: Enter both numbers and click Calculate.

Expected Result: Result should display 30.

Actual Result: Result displays 30.

Status: Pass.

Test cases help developers and testers organize their testing activities.

13. What Is Regression Testing?

Regression Testing means running existing tests again after changing application code.

For example, suppose your calculator originally supports addition and subtraction. Later, you add multiplication and modify the calculation logic.

You should run the existing tests again to make sure addition and subtraction still work.

Regression testing helps prevent new code changes from breaking previously working features.

14. Manual Testing vs Unit Testing vs UI Testing

Manual Testing

  • Performed by a person.

  • Does not require automated test code.

  • Useful for visual and usability checks.

  • Repeated testing can take time.

Unit Testing

  • Tests individual methods or classes.

  • Commonly uses JUnit.

  • Local tests run on the JVM.

  • Useful for checking business logic.

UI Testing

  • Tests application screens and interactions.

  • Can use Espresso.

  • Instrumented UI tests run on a device or emulator.

  • Useful for verifying user workflows.

A good Android testing strategy uses these approaches together. They solve different testing problems and should not be treated as replacements for one another.

15. Best Practices for Android App Testing

  • Write unit tests for important business logic.

  • Test both valid and invalid input.

  • Include boundary cases and unexpected values.

  • Use UI tests for important user workflows.

  • Perform manual testing on different screen sizes.

  • Test on emulators and real devices when possible.

  • Run regression tests after code changes.

  • Keep test methods small and independent.

  • Use meaningful test names.

  • Do not ignore failed tests.

16. Conclusion

Testing helps developers build stable, reliable, and user-friendly Android applications.

Manual Testing verifies the application from a user's perspective. Unit Testing checks individual methods and classes using frameworks such as JUnit. UI Testing verifies application screens and user interactions using tools such as Espresso.

In this tutorial, we created a Java Calculator application, wrote JUnit tests for its calculation methods, and created an Espresso test to verify its user interface.

By practising these testing methods, you can identify bugs earlier and improve the quality of your Android applications.

17. Frequently Asked Questions

Q1. What is Android app testing?

Android app testing is the process of checking an application's functionality, performance, user interface, and reliability.

Q2. What is JUnit?

JUnit is a Java testing framework used to write and execute automated unit tests.

Q3. What is Espresso?

Espresso is an Android UI testing framework used to automate interactions with application views.

Q4. Where are local unit tests stored?

Local unit tests are generally stored inside app/src/test/java/.

Q5. Where are instrumented tests stored?

Instrumented tests are generally stored inside app/src/androidTest/java/.

Q6. What is the difference between unit testing and UI testing?

Unit testing checks individual pieces of code, while UI testing checks how the application's interface behaves during user interactions.

Q7. What is regression testing?

Regression testing means running existing tests again after code changes to verify that previously working features still work correctly.

Q8. Can Android testing be performed on a real phone?

Yes. Instrumented tests and Espresso UI tests can run on a physical Android phone with USB debugging enabled or on a compatible emulator.

←
Post 35 of 40
→