๐Ÿ› ๏ธ AI Tools for Android Developers

AI-Assisted Unit Test Generation for Android

AI can write dozens of unit tests in seconds, and many of them will test nothing useful. The trick is to make AI think about behaviour and edge cases first, use your test conventions, and review tests as critically as production code.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Intermediate
On this page
  1. Edge cases first, then tests
  2. Prompts that produce useful tests
  3. Example result, reviewed
  4. Recognising weak AI tests
  5. Check that tests can fail
  6. Where AI test generation pays off
  7. Frequently asked questions
  8. Conclusion

An AI-generated test that calls a function and asserts the result is "not null" adds coverage and no safety. Good tests encode behaviour: given this situation, the app must do that. AI can help enumerate situations, and you decide which behaviours matter.

Edge cases first, then tests

Workflow for AI-assisted test generation Ask AI to list behaviours and edge cases, curate the list yourself, generate tests using project conventions and fakes, run them and deliberately break the code to see tests fail, then keep only meaningful tests. List casesAI brainstorm Curateyou decide Generateyour conventions Break codetests must fail Keep gooddelete weak
A test that still passes when you break the code is not protecting anything.

Prompts that produce useful tests

Step 1: behaviours and edge casesText
Here is CheckoutViewModel and its UiState. List the behaviours and edge cases worth testing:
user actions, success/failure paths, boundary values, concurrency (double taps), and
state after errors. Don't write code yet. Group them by priority.
Step 2: tests with conventionsText
Write JUnit4 tests for cases 1, 2, 4 and 7 only.
Conventions: MainDispatcherRule from com.example.testing, runTest, FakeCartRepository
and FakePaymentRepository (no mocking libraries), backtick test names describing behaviour,
one behaviour per test, assert on uiState values only.

Example result, reviewed

CheckoutViewModelTest.ktKotlin
class CheckoutViewModelTest {
    @get:Rule val mainRule = MainDispatcherRule()

    @Test
    fun `double tap on pay submits only one payment`() = runTest {
        val payments = FakePaymentRepository(delayMs = 1_000)
        val vm = CheckoutViewModel(FakeCartRepository(total = 49_900), payments)

        vm.onPayClick(); vm.onPayClick()
        advanceUntilIdle()

        assertEquals(1, payments.submittedCount)                      // guards against duplicate charges
    }

    @Test
    fun `payment failure keeps cart and shows retryable error`() = runTest {
        val vm = CheckoutViewModel(FakeCartRepository(total = 49_900), FakePaymentRepository(fail = true))

        vm.onPayClick(); advanceUntilIdle()

        val state = vm.uiState.value
        assertEquals(49_900, state.totalPaise)
        assertTrue(state.error?.canRetry == true)
        assertFalse(state.isProcessing)
    }
}

These are worth keeping: each protects a real business rule, and each fails if the behaviour regresses.

Recognising weak AI tests

SmellExampleFix
Asserts nothing meaningfulassertNotNull(vm.uiState.value)Assert specific state values
Mirrors the implementationRecomputes the expected total with the same formulaUse known, hand-calculated values
Over-mockingVerifies every repository callUse fakes; assert outcomes
Flaky timingThread.sleep, real dispatchersTest dispatchers, virtual time
Tests framework behaviourAsserting Room or Retrofit internals in unit testsTest your logic; integration tests elsewhere

Check that tests can fail

Manually introduce a bug (flip a condition, remove a guard) and run the tests. At least one should fail. Mutation-testing tools automate this idea on the JVM, but even a few manual mutations reveal hollow tests quickly.

Where AI test generation pays off

Legacy code with no tests

AI drafts characterization tests capturing current behaviour before a refactor. See Refactoring Legacy Apps.

Mappers and validators

Table-driven tests of many input variations, with hand-checked expected values.

Edge-case discovery

The brainstorm step often surfaces cases the team missed, such as double taps, empty states and time zones.

Frequently asked questions

Should coverage targets drive AI test generation?

No. Coverage encourages hollow tests. Target behaviours and risks, and use coverage only to find untested risky code.

Can AI generate UI tests?

It can draft Compose UI tests and screenshot previews, but they need the same review: realistic states, stable selectors and meaningful assertions.

What about Android Studio's test generation?

Gemini in Android Studio can generate unit tests for a class. Treat the output as a draft, and apply the review steps above.

Conclusion

Use AI to enumerate edge cases and draft tests in your conventions, then curate them, prove they fail when code breaks, and delete hollow ones. Good AI-assisted tests protect behaviours, not coverage numbers.

Next step: use AI on failures in Debugging Android Errors with AI.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

AI coding tools multiply what you already know. The stronger your Kotlin, Compose and architecture foundation, the better you can judge, fix and ship what these tools suggest.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp