Android Application Testing
Relevant source files
The following files were used as context for generating this wiki page:
- AGENTS.md
- README.md
- app/src/test/java/io/github/mojri/hesabyar/rust/RustBridgeTest.kt
- app/src/test/java/io/github/mojri/hesabyar/domain/usecase/ManageBackupUseCaseValidationTest.kt
- rust/hesabyar-core/README.md
- app/src/test/java/io/github/mojri/hesabyar/CategoryTest.kt
- app/src/test/java/io/github/mojri/hesabyar/GeminiParserLogLevelTest.kt
- rust/hesabyar-core/src/ai_validation.rs
Android application testing in the Hesabyar project follows a multi-layered approach that ensures the integrity of financial logic, Persian NLP capabilities, and the bridge between Kotlin and the native Rust core. The project utilizes unit testing for both the Android app (Kotlin) and the shared logic (Rust), supplemented by screenshot testing and performance benchmarking.
The testing infrastructure is designed to validate the "offline-first" nature of the application, ensuring that core financial calculations, Jalali calendar conversions, and local data management remain accurate across releases.
Sources: AGENTS.md:73-77, README.md:144-154, rust/hesabyar-core/README.md:94-105
Testing Architecture
The testing architecture is split across two primary environments: the JVM (Kotlin/Android) and the Native (Rust) environment.
Kotlin Unit Testing (JVM)
Kotlin unit tests are located in app/src/test/. These tests leverage JUnit, Robolectric for Android environment simulation, and Roborazzi for screenshot-based regression testing. A key aspect of these tests is exercising the RustBridge, which allows the JVM to load and verify the hesabyar_core native library during unit test execution.
Sources: AGENTS.md:73-77, app/src/test/java/io/github/mojri/hesabyar/rust/RustBridgeTest.kt:14-23
Rust Core Testing (Native)
The hesabyar-core library contains its own suite of unit tests and benchmarks. These are critical for validating business logic that is shared between Android and potential future platforms.
Sources: rust/hesabyar-core/README.md:9-25, rust/hesabyar-core/README.md:94-105
Test Data Flow
The following diagram illustrates how tests interact with the application components and the native bridge.
The diagram shows the interaction between Kotlin unit tests, the application use cases/parsers, and the underlying Rust core via the RustBridge and UniFFI.
Sources: app/src/test/java/io/github/mojri/hesabyar/rust/RustBridgeTest.kt:14-23, rust/hesabyar-core/README.md:65-72
Key Testing Components
Native Bridge Verification
The RustBridgeTest class ensures that the Kotlin-to-Rust delegation path is functional. It verifies that core features like Jalali calendar conversion, currency formatting, and AI response validation correctly invoke native logic.
| Test Category | Description | Derived Source |
|---|---|---|
| Calendar Sync | Validates Gregorian-to-Jalali conversion and leap year detection. | RustBridgeTest.kt:39-48 |
| Currency Sync | Ensures numeric formatting remains locale-independent (ASCII digits). | RustBridgeTest.kt:55-68 |
| Parser Sync | Tests offline Persian sentence parsing and money detection. | RustBridgeTest.kt:75-87 |
| Entity Validation | Checks if Rust correctly validates Transaction, Loan, and Installment objects. | RustBridgeTest.kt:111-150 |
AI and NLP Validation
Testing includes verifying the behavior of AI-driven features. This involves checking logs via Robolectric ShadowLog to ensure appropriate debug levels and privacy (no full AI response text in logs).
Sources: app/src/test/java/io/github/mojri/hesabyar/GeminiParserLogLevelTest.kt:38-59
Backup and Data Integrity
The ManageBackupUseCaseValidationTest exercises the native path for validating JSON backup payloads. It ensures that well-formed payloads are accepted while malformed data (e.g., transactions with zero or negative amounts) is rejected.
Sources: app/src/test/java/io/github/mojri/hesabyar/domain/usecase/ManageBackupUseCaseValidationTest.kt:38-89
Rust Core Internal Testing
The Rust core (hesabyar-core) includes extensive internal tests, particularly for the AI validation logic located in ai_validation.rs.
AI Transaction Parsing Logic
The following sequence diagram demonstrates the internal validation flow when the Rust core processes an AI-generated JSON response.
The diagram outlines how the Rust core deserializes, normalizes, and validates AI transaction data before returning it to the Kotlin layer.
Sources: rust/hesabyar-core/src/ai_validation.rs:114-233
Validation Rules for AI Output
Testing in ai_validation.rs covers specific "repair" scenarios where the system coerces invalid AI output into safe defaults:
- Categories: Maps extended categories (e.g., "Personal Care") to core types ("Shopping").
- Types: Maps unknown transaction types to "EXPENSE".
- Confidence: Defaults missing or out-of-range confidence values to
0.8. - Time: Clamps hours to
0-23and minutes to0-59.
Sources: rust/hesabyar-core/src/ai_validation.rs:64-105, rust/hesabyar-core/src/ai_validation.rs:374-450
Testing Execution and Commands
The project uses Gradle for Android tests and Cargo for Rust core tests.
Execution Commands
# Run all Kotlin unit tests
./gradlew test --no-daemon
# Run a specific Kotlin test class
./gradlew test --tests "io.github.mojri.hesabyar.TransactionTest" --no-daemon
# Run Rust core unit tests
cd rust/hesabyar-core
cargo test
# Run Rust benchmarks
cargo bench
Sources: AGENTS.md:14-23, README.md:188-193, rust/hesabyar-core/README.md:38-44
CI/CD and Static Analysis
The project enforces code quality through static analysis and linting, which are integrated into the testing workflow.
- Linting:
./gradlew lint - Detekt/ktlint:
./gradlew ktlintCheck detekt - Baseline Management: The project maintains
lint-baseline.xmlanddetekt-baseline.xmlto manage existing technical debt and focus on new regressions.
Sources: AGENTS.md:25-26, AGENTS.md:108-112, config/detekt/detekt-baseline.xml, app/lint-baseline.xml
Performance Benchmarking
Performance is monitored using multiple tools to ensure that the "hot" paths (like currency parsing and Jalali conversion) remain efficient.
- Criterion: Used in the Rust core for high-precision micro-benchmarking of the Persian NLP parser.
- JMH: Used for JVM-based performance analysis.
- CodSpeed: Integrated into the CI pipeline to track performance regressions on Pull Requests.
Sources: README.md:204-219, rust/hesabyar-core/README.md:103-105
In summary, Android Application Testing in Hesabyar is a comprehensive system that bridges high-level UI verification with low-level native logic validation. By utilizing multi-language testing frameworks and automated quality checks, the project ensures financial accuracy and UX consistency for its Persian-speaking user base.