MyFamilyTracker
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
Testing and QA are not the same discipline. This post breaks down the real difference, shows how I apply both across 22+ production Android apps, and gives you 2026-ready practices you can ship with today.
On this page
Most Android developers use “testing” and “QA” like they mean the same thing. They don’t, and that confusion is why solo developers ship broken releases and burn out fixing fires.
After 13+ years in QA and building 22+ apps at SudarshanTechLabs from Bangkok, I treat testing as a subset of QA, not a replacement for it. If you are a solo dev in 2026, that distinction is the difference between surviving and scaling.
When you work alone, there is no separate QA team to catch your blind spots. You write the feature, you write the test, you hit publish. That workflow feels like QA, but it is usually just testing with extra steps.
Testing answers one question: does this code do what I intended? QA answers a harder question: will this app hold up in the real world across devices, networks, and angry users?
I learned this the hard way in 2019 when one of my early apps passed every unit test but crashed on Samsung devices in Thailand because of a locale-specific date parse bug. The tests were green. The QA was absent.
[!WARNING] A green test suite does not mean your app is safe to release. It means your code matches your assumptions, which are often wrong under real conditions.
Testing is tactical. It is code that verifies code. In 2026, my default Android stack is Kotlin, Jetpack Compose, StateFlow, and Hilt, with tests split across three layers.
Here is a real unit test from one of my production apps that validates a ViewModel using Turbine and MockK:
@Test
fun `loadProfile emits loading then success`() = runTest {
val fakeRepo = mockk<ProfileRepository>()
coEvery { fakeRepo.getProfile("u1") } returns Profile("u1", "Sudarshan")
val vm = ProfileViewModel(fakeRepo)
vm.uiState.test {
assertEquals(UiState.Loading, awaitItem())
vm.loadProfile("u1")
assertEquals(UiState.Success(Profile("u1", "Sudarshan")), awaitItem())
}
}This test is fast, deterministic, and cheap. It proves the ViewModel logic is correct. It says nothing about whether the screen is usable on a low-end Android Go device.
I use this breakdown for every app I maintain:
| Test Type | Scope | Tooling (2026) | Speed |
|---|---|---|---|
| Unit | Logic, ViewModels, mappers | JUnit5, MockK, Turbine | ms |
| Integration | Room, Hilt, repositories | AndroidX Test, HiltAndroidRule | sec |
| UI | Compose screens, flows | Compose UI Test, Maestro | min |
Testing is the part of quality you can automate on your laptop. It is necessary and insufficient.
[!NOTE] In 2026, Compose UI tests with semantics tags are far more stable than old Espresso view-id hunting. Tag your UI by meaning, not by layout.
QA is strategic. It is the practice of designing release confidence. For a solo dev, QA is the operating system around your tests: device coverage, staged rolls, crash monitoring, and user feedback loops.
My QA checklist for every Play Store release in 2026 includes:
That last item is QA, not testing. No test caught the foldable resize bug I found by literally opening the app on a Pixel Fold.
[!TIP] Use Play Console staged rollouts even if you have zero users. A 5% rollout turns a global crash into a contained incident and protects your store rating.
Here is the GitHub Actions workflow I use to enforce testing before merge:
name: android-ci
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- run: ./gradlew testDebugUnitTest
- run: ./gradlew connectedCheckThis is testing automation. QA is deciding that this must run before any merge and that a red build blocks shipping.
The gap between testing and QA is where solo devs lose apps. These are the practices I use across all 22+ apps to close it.
Write tests while coding, not after. But also define acceptance criteria before coding. A one-line note in your issue tracker like “must work offline with cached Room data” is a QA artifact, not a test.
In 2026, I use Claude Code to generate test scaffolding and review diffs for untested paths. It is not QA. I still manually verify Compose animations and gesture behavior because AI cannot feel jank.
Solo does not mean blind. Firebase Crashlytics, Play Vitality, and anonymized analytics are your night-shift QA engineers.
| Old Solo Habit (2020) | 2026 Practice |
|---|---|
| Ship to 100% immediately | 5% staged rollout + Crashlytics |
| Test on one emulator | Real low-end + foldable device |
| Assume green tests = safe | Closed track + user feedback |
| Manual APK side-load | CI build + Play internal track |
[!IMPORTANT] QA for a solo dev is not a department. It is a repeatable system that catches what your tests cannot see.
Sudarshan Chaudhari
AI Systems Builder / Product Engineer
Bangkok, Thailand
Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.
Related Posts
Related Apps
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
Building something? Available for Android dev and QA consulting.
Work with meComments — powered by Giscus