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.
A detailed, battle-tested checklist for solo Android developers to ensure stable, secure, and high-performance releases. Covers automated testing, CI/CD, performance monitoring, and final sanity checks.
On this page
In the past two years, I've shipped over 50 Android app updates without a single critical crash or user-facing regression. As a solo developer with a QA background, I learned early that a rigorous release process isn't optional—it's the price of sanity. This checklist is my non-negotiable system for shipping confidently.
When you're the only engineer, designer, and product manager, a single bad release can destroy user trust, flood you with support tickets, and set your project back weeks. My 13+ years in QA taught me that release quality is a process, not luck. Without a systematic approach, even simple updates can introduce subtle bugs that slip through manual testing. This checklist evolved from real failures—each item here solves a problem I've personally faced.
Every release starts with a locked testing gate. I require 100% unit test coverage on all new code and critical paths, plus a robust UI test suite that runs on every commit. My rule: if a test can't be automated, it's not a reliable check.
I use a tiered testing strategy:
// Example: A unit test for a login use case
@Test
fun `login with valid credentials succeeds`() = runTest {
val mockRepo = mock<AuthRepository> {
on { login("user@example.com", "password123") } doReturn Result.success(User("John"))
}
val useCase = LoginUseCase(mockRepo)
val result = useCase("user@example.com", "password123")
assertTrue(result.isSuccess)
assertEquals("John", result.getOrThrow().name)
}[!IMPORTANT]
Tests must run in isolation and fail fast. I configure Gradle to stop the build on the first test failure.
| Test Type | Minimum Coverage | Execution Time |
|---|---|---|
| Unit Tests | 100% of new code | < 2 minutes |
| UI Tests | Critical paths only | < 5 minutes |
| E2E Tests | Core user journeys | < 10 minutes |
I enforce these thresholds with a custom Gradle task that blocks the release build if any metric falls short.
My CI pipeline is the engine that enforces the checklist. I use GitHub Actions because it's cost-effective for solo projects and integrates seamlessly with Play Store.
The pipeline has three stages:
# .github/workflows/release.yml (simplified)
name: Release Pipeline
on:
push:
branches: [main]
tags: ['v*']
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
- name: Run unit tests
run: ./gradlew testDebugUnitTest
- name: Run UI tests
run: ./gradlew connectedDebugAndroidTest
build:
needs: test
runs-on: ubuntu-latest
steps:
- name: Build signed bundle
run: ./gradlew bundleRelease
env:
SIGNING_KEY: ${{ secrets.ANDROID_SIGNING_KEY }}
validate:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to internal track
uses: rorochamp/android-play-publisher@v1
with:
service_account_json: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
package_name: com.sudarshantechlabs.myapp
track: internal
apk_path: app/build/outputs/bundle/release/app-release.aab[!TIP]
Always use a separate internal test track in the Play Console. It's your safety net for real-device validation without affecting production users.
Even with perfect tests, production is unpredictable. I monitor four key metrics: crash rate, ANR rate, API latency, and battery impact. My threshold for release is simple: zero critical crashes and ANR rate below 0.1%.
I use Firebase Crashlytics for crash reporting and Performance Monitoring for real-time metrics. The setup is straightforward but critical:
// Initialize Crashlytics and Performance Monitoring
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true)
FirebasePerformance.getInstance().startTrace("app_startup")
}
}| Metric | Green Zone | Yellow Zone | Red Zone (Block Release) |
|---|---|---|---|
| Crash Rate | < 0.01% | 0.01% - 0.1% | > 0.1% |
| ANR Rate | 0% | < 0.05% | > 0.05% |
| API Latency (95th) | < 500ms | 500ms - 2s | > 2s |
| Battery Impact | Negligible | Moderate | High |
Before every release, I review the last 7 days of data from the internal test track. If any metric is in the red zone, I halt the release until it's fixed.
Automation catches 95% of issues, but the final 5% require human judgment. I run through this checklist on a physical device (not an emulator) the day before release.
| Check | Pass/Fail | Notes |
|---|---|---|
| App installs from Play Store | ✅ | Not just from ADB |
| First-launch tutorial works | ✅ | For new users |
| Push notifications trigger | ✅ | Use Firebase Console |
| Offline mode handles gracefully | ✅ | Airplane mode test |
| Permissions request correctly | ✅ | Camera, location, etc. |
| Deep links open proper screens | ✅ | From browser/email |
| Accessibility services work | ✅ | TalkBack enabled |
| Battery optimization exempt | ✅ | Settings > Battery |
| Data usage in background | ✅ | < 10MB/day |
| Play Store listing screenshots match | ✅ | No surprises |
[!WARNING]
Never skip the physical device test. Emulators don't replicate real-world conditions like network switching, battery drain, or manufacturer-specific quirks.
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
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
ReadPrivate dream journal — structured entry capture, pattern tagging, and optional Claude-powered insight generation. All data stays on-device by default.
ReadWorkout tracker — exercise logging with set/rep/weight history, goal progression, and local Room DB persistence. No account, no cloud sync required.
Read