Skip to content

UI Testing (Espresso)

# UI Testing in Android

## What is UI Testing?
UI (User Interface) Testing ensures that the visual and interactive elements of your Android application behave as expected.  
It verifies:
- Screen layouts (views, buttons, text fields, etc.)
- User interactions (clicks, swipes, typing)
- Navigation between screens
- Accessibility features like TalkBack

In short, UI testing helps confirm that the app works correctly from a **userโ€™s perspective**.

---

## Why UI Testing is Important
- Detects **UI/UX regressions** early
- Ensures **accessibility compliance** (screen readers, large fonts, dark mode, etc.)
- Validates the **user flow** (navigation, inputs, dialogs)
- Increases confidence when releasing new features

---

## Types of UI Testing in Android
1. **Manual UI Testing**
   - Performed by testers or developers.
   - Involves going through the app step by step.
   - Example: Opening the app, checking if the login button works.

2. **Automated UI Testing**
   - Uses frameworks to simulate user interactions.
   - Example: Espresso test that clicks a button and checks the result.
   - Benefits: Faster, repeatable, less prone to human error.

---

## Tools for UI Testing
- **Espresso (AndroidX Test)**
  - Official Android framework for writing UI tests.
  - Good for small to medium apps.

- **UI Automator**
  - Tests across multiple apps or system UI.
  - Example: Interacting with system dialogs.

- **Robolectric**
  - Runs tests on the JVM without requiring an emulator/device.
  - Great for unit + UI component tests.

- **Appium**
  - Cross-platform testing tool (Android & iOS).
  - Useful for larger projects with multiple platforms.

---

## Example: Espresso Test
```kotlin
@RunWith(AndroidJUnit4::class)
class LoginUITest {

    @get:Rule
    val activityRule = ActivityScenarioRule(MainActivity::class.java)

    @Test
    fun testLoginButtonVisible() {
        // Check if login button is displayed
        onView(withId(R.id.loginButton))
            .check(matches(isDisplayed()))
    }

    @Test
    fun testLoginFlow() {
        // Enter text in username and password fields
        onView(withId(R.id.usernameField)).perform(typeText("testuser"))
        onView(withId(R.id.passwordField)).perform(typeText("password"))

        // Close soft keyboard
        closeSoftKeyboard()

        // Click login button
        onView(withId(R.id.loginButton)).perform(click())

        // Verify navigation to home screen
        onView(withId(R.id.homeScreen))
            .check(matches(isDisplayed()))
    }
}

Best Practices

  • Keep tests short and focused (test one user flow per case).
  • Use mock data to avoid dependency on backend.
  • Always test accessibility (TalkBack, large font, color contrast).
  • Run tests on multiple screen sizes and Android versions.
  • Integrate UI tests in CI/CD pipelines (GitHub Actions, Jenkins, etc.).

Manual vs Automated UI Testing

Aspect Manual Testing Automated Testing
Speed Slow (human effort) Fast (runs on emulator/device)
Reliability Can miss issues Repeatable, consistent
Cost Cheaper upfront Investment in writing tests
Best Use Exploratory testing Regression & frequent release apps

Next Steps

Since your project doesnโ€™t yet have UI tests:

  1. Start with manual UI test cases (Excel sheet format).
  2. Gradually add Espresso tests for critical user flows (like login, game start, result dialogs).
  3. Later, integrate into CI so tests run automatically on each PR/commit.