Skip to content

Latest commit

Β 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

UITestDemo - Modern Android App Template

Android CI Kotlin License

A production-ready Android application demonstrating modern Android development best practices, including Clean Architecture, MVVM pattern, Jetpack Compose, offline-first approach with Room database, comprehensive testing, and CI/CD.

πŸ“± Screenshots

✨ Features

  • πŸ—οΈ Clean Architecture - Separation of concerns with clear layer boundaries
  • πŸ“± MVVM Pattern - Reactive UI with ViewModels and StateFlow
  • 🎨 Jetpack Compose - Modern declarative UI toolkit
  • πŸ’Ύ Offline-First - Room database with cache-first strategy (5-minute cache timeout)
  • πŸ”Œ Networking - Retrofit with proper error handling
  • πŸ’‰ Dependency Injection - Hilt for clean, testable code
  • πŸ§ͺ Comprehensive Testing - Unit tests, UI tests, and integration tests (33 tests total)
  • πŸ” Code Quality - Detekt static analysis with custom rules
  • πŸš€ CI/CD - GitHub Actions for automated testing and builds
  • 🎯 Edge-to-Edge UI - Modern Material 3 design with proper window insets
  • ⚑ Performance - ProGuard/R8 optimization for release builds

πŸ› οΈ Tech Stack

Core

  • Kotlin 2.3.10
  • Min SDK 30 (Android 11)
  • Target SDK 36

UI

  • Jetpack Compose 2026.02.00 BOM
  • Material 3 - Modern Material Design
  • Compose Navigation - For multi-screen apps
  • Hilt Navigation Compose - ViewModel integration

Architecture

  • Hilt 2.59.2 - Dependency Injection
  • Coroutines 1.10.2 - Asynchronous programming
  • StateFlow - Reactive state management

Networking

  • Retrofit 3.0.0 - HTTP client
  • Gson - JSON serialization
  • OkHttp Logging Interceptor - Network debugging

Database

  • Room 2.8.4 - Local persistence
  • Room KTX - Coroutines support

Testing

  • JUnit 4.13.2 - Unit testing framework
  • Kotlin Test - Kotlin-specific assertions
  • MockK 1.14.9 - Mocking library
  • Turbine 1.2.1 - Flow testing
  • Coroutines Test - Coroutine testing utilities
  • Compose UI Test - UI testing
  • Hilt Testing - DI testing support

Code Quality

  • Detekt 1.23.8 - Static code analysis
  • KSP 2.3.4 - Annotation processing

πŸ—οΈ Architecture

This project follows Clean Architecture principles with three main layers:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Presentation Layer              β”‚
β”‚  - UI (Compose)                         β”‚
β”‚  - ViewModels                           β”‚
β”‚  - UI State                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓ ↑
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Domain Layer                    β”‚
β”‚  - Use Cases                            β”‚
β”‚  - Domain Models                        β”‚
β”‚  - Repository Interfaces                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓ ↑
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Data Layer                      β”‚
β”‚  - Repository Implementations           β”‚
β”‚  - Local Database (Room)                β”‚
β”‚  - Remote API (Retrofit)                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Package Structure

app/src/main/java/io/codetheworld/uitestdemo/
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ di/                 # Dependency injection modules
β”‚   β”‚   β”œβ”€β”€ AppModule.kt
β”‚   β”‚   β”œβ”€β”€ DatabaseModule.kt
β”‚   β”‚   └── NetworkModule.kt
β”‚   └── network/            # Network utilities
β”‚       β”œβ”€β”€ ApiService.kt
β”‚       β”œβ”€β”€ NetworkConstants.kt
β”‚       └── NetworkResult.kt
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ local/             # Room database
β”‚   β”‚   β”œβ”€β”€ AppDatabase.kt
β”‚   β”‚   β”œβ”€β”€ dao/
β”‚   β”‚   β”‚   └── PostDao.kt
β”‚   β”‚   └── entity/
β”‚   β”‚       └── PostEntity.kt
β”‚   └── repository/        # Repository implementations
β”‚       └── PostRepositoryImpl.kt
β”œβ”€β”€ domain/
β”‚   β”œβ”€β”€ model/             # Domain models
β”‚   β”‚   └── Post.kt
β”‚   β”œβ”€β”€ repository/        # Repository interfaces
β”‚   β”‚   └── PostRepository.kt
β”‚   └── usecase/           # Business logic
β”‚       └── GetPostsUseCase.kt
└── ui/
    β”œβ”€β”€ post/              # Post feature
    β”‚   β”œβ”€β”€ PostScreen.kt
    β”‚   β”œβ”€β”€ PostUiState.kt
    β”‚   β”œβ”€β”€ PostViewModel.kt
    β”‚   └── UiError.kt
    └── theme/             # App theming
        β”œβ”€β”€ Color.kt
        β”œβ”€β”€ Theme.kt
        └── Type.kt

πŸš€ Getting Started

Prerequisites

  • Android Studio Ladybug | 2024.2.1 or later
  • JDK 17 or later
  • Android SDK 36
  • Gradle 9.2.1

Installation

  1. Clone the repository
git clone https://github.com/yourusername/UITestDemo.git
cd UITestDemo
  1. Open the project in Android Studio

  2. Sync Gradle files

  3. Run the app

./gradlew assembleDebug

Running Tests

Unit Tests:

./gradlew test

UI Tests:

./gradlew connectedAndroidTest

Code Quality Check:

./gradlew detekt

All Quality Checks:

./gradlew test detekt assembleDebug

πŸ§ͺ Testing Strategy

The project includes comprehensive testing:

  • Unit Tests (27 tests)

    • ViewModel tests with Turbine
    • Repository tests with MockK
    • Use case tests
    • Error mapping tests
  • UI Tests (3 tests)

    • Compose UI tests
    • Hilt integration tests
    • End-to-end flows
  • Integration Tests

    • Repository with fake dependencies

Test Coverage: ~85%

Test Examples

ViewModel Test:

@Test
fun `init loads posts successfully`() = runTest {
    // Given
    coEvery { getPostsUseCase() } returns NetworkResult.Success(testPosts)

    // When
    viewModel = PostViewModel(getPostsUseCase)
    testDispatcher.scheduler.advanceUntilIdle()

    // Then
    viewModel.uiState.test {
        val state = awaitItem()
        assertFalse(state.isLoading)
        assertEquals(testPosts, state.posts)
    }
}

🎯 Key Features Explained

Offline-First Architecture

The app implements a cache-first strategy:

  1. Check local cache first - Always try to serve from cache
  2. Validate cache - Check if cache is fresh (< 5 minutes)
  3. Return valid cache immediately - No network call needed
  4. Fetch on stale/empty - Only call network if necessary
  5. Fallback to cache - On network errors, return stale cache

Benefits:

  • ⚑ Instant app startup
  • πŸ“΄ Works offline
  • πŸ”‹ Reduced battery usage
  • πŸ“Š Lower data consumption

Error Handling

Type-safe error handling with sealed classes:

sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    sealed class Error : NetworkResult<Nothing>() {
        data object NetworkError : Error()
        data class ServerError(val code: Int) : Error()
        data class UnknownError(val message: String?) : Error()
    }
}

User-friendly error messages:

  • Network errors: "No internet connection. Please check your network."
  • Server errors: Specific messages based on HTTP status codes
  • Unknown errors: Graceful degradation

Dependency Injection

Using Hilt for dependency management:

@HiltViewModel
class PostViewModel @Inject constructor(
    private val getPostsUseCase: GetPostsUseCase
) : ViewModel()

All dependencies are provided through DI, making the code:

  • Testable (easy to inject mocks)
  • Maintainable (centralized dependency management)
  • Scalable (easy to swap implementations)

πŸ“Š Code Quality

Detekt Configuration

The project uses Detekt with custom rules:

complexity:
  LongMethod: threshold: 60
  LargeClass: threshold: 600
  CyclomaticComplexMethod: threshold: 15

style:
  MaxLineLength: 120

Run code quality checks:

./gradlew detekt

View HTML report:

app/build/reports/detekt/detekt.html

πŸ”„ CI/CD Pipeline

GitHub Actions workflow runs on every push and PR:

βœ… Code quality check (Detekt) βœ… Unit tests βœ… Build debug APK βœ… Build Android test APK βœ… Upload test results

See .github/workflows/ci.yml for details.

πŸ›£οΈ Roadmap

  • Add pagination for large lists
  • Implement pull-to-refresh
  • Add search functionality
  • Implement multi-module architecture
  • Add more comprehensive UI tests
  • Integrate Firebase Analytics
  • Add crash reporting (Firebase Crashlytics)
  • Implement dark theme support
  • Add accessibility features
  • Baseline profiles for performance

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Code Style

  • Follow Kotlin coding conventions
  • Run Detekt before committing: ./gradlew detekt
  • Ensure all tests pass: ./gradlew test
  • Add tests for new features

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ‘¨β€πŸ’» Author

Your Name

πŸ™ Acknowledgments

πŸ“š Resources


Built with ❀️ using Kotlin and Jetpack Compose

If you found this project helpful, please ⭐ star the repository!

About

Production-ready Android app template showcasing Clean Architecture, MVVM, Jetpack Compose, offline-first caching with Room, comprehensive testing (85% coverage), and CI/CD with GitHub Actions.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages