mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
6 KiB
6 KiB
Testing Consolidation: core:testing Module
Date: 2026-03-11 Status: Implemented Scope: KMP test consolidation across all core and feature modules
Overview
Created core:testing as a lightweight, reusable module for shared test doubles, fakes, and utilities across all Meshtastic-Android KMP modules. This consolidates testing dependencies and keeps the module dependency graph clean.
Design Principles
1. Lightweight Dependencies Only
core:testing
├── depends on: core:model, core:repository
├── depends on: kotlin("test"), kotlinx.coroutines.test, turbine, junit
└── does NOT depend on: core:database, core:data, core:domain
Rationale: core:database has KSP processor dependencies that can slow builds. Isolating core:testing with minimal deps ensures:
- Fast compilation of test infrastructure
- No circular dependency risk
- Modules depending on
core:testing(viacommonTest) don't drag heavy transitive deps
2. No Production Code Leakage
:core:testingis declared only incommonTestsourceSet, never incommonMain- Test code never appears in APKs or release JARs
- Strict separation between production and test concerns
3. Dependency Graph
┌─────────────────────┐
│ core:testing │
│ (light: model, │
│ repository) │
└──────────┬──────────┘
│ (commonTest only)
┌────┴─────────┬───────────────┐
↓ ↓ ↓
core:domain feature:messaging feature:node
core:data feature:settings etc.
Heavy modules (core:domain, core:data) depend on :core:testing in their test sources, not vice versa.
Consolidation Strategy
What Was Unified
Before:
// Each module's build.gradle.kts had scattered test deps
commonTest.dependencies {
implementation(libs.junit)
implementation(libs.mockk)
implementation(libs.kotlinx.coroutines.test)
implementation(libs.turbine)
}
After:
// All modules converge on single dependency
commonTest.dependencies {
implementation(projects.core.testing)
}
// core:testing re-exports all test libraries
Modules Updated
- ✅
core:domain— test doubles for domain logic - ✅
feature:messaging— commonTest bootstrap - ✅
feature:settings,feature:node,feature:intro,feature:map,feature:firmware
What's Included
Test Doubles (Fakes)
FakeRadioController— No-opRadioControllerwith call trackingFakeNodeRepository— In-memoryNodeRepositoryfor isolated tests- (Extensible) — Add new fakes as needed
Test Builders & Factories
TestDataFactory— Create domain objects (nodes, users) with sensible defaultsval node = TestDataFactory.createTestNode(num = 42) val nodes = TestDataFactory.createTestNodes(count = 10)
Test Utilities
- Flow collection helper —
flow.toList()for assertions
Benefits
| Aspect | Before | After |
|---|---|---|
| Dependency Duplication | Each module lists test libs separately | Single consolidated dependency |
| Build Purity | Test deps scattered across modules | One central, curated source |
| Dependency Graph | Risk of circular deps or conflicting versions | Clean, acyclic graph with minimal weights |
| Reusability | Fakes live in test sources of single module | Shared across all modules via core:testing |
| Maintenance | Updating test libs touches multiple files | Single core:testing/build.gradle.kts |
Maintenance Guidelines
Adding a New Test Double
- Implement the interface from
core:modelorcore:repository - Add call tracking for assertions (e.g.,
sentPackets,callHistory) - Provide test helpers (e.g.,
setNodes(),clear()) - Document with KDoc and example usage
When Adding a New Module with Tests
- Add
implementation(projects.core.testing)to itscommonTest.dependencies - Reuse existing fakes; create new ones only if genuinely reusable
When Updating Repository Interfaces
- Update corresponding fakes in
:core:testingto match new signatures - Fakes remain no-op; don't replicate business logic
Files & Documentation
core/testing/build.gradle.kts— Minimal dependencies, KMP targetscore/testing/README.md— Comprehensive usage guide with examplesAGENTS.md— Updated with:core:testingdescription and testing rulesfeature/messaging/src/commonTest/— Bootstrap example test
Next Steps
- Monitor compilation times — Verify that isolating
core:testingimproves build speed - Add more fakes as needed — As feature modules add comprehensive tests, add fakes to
core:testing - Consider feature-specific extensions — If a feature needs heavy, specialized test setup, keep it local; don't bloat
core:testing - Cross-module test sharing — Enable tests across modules to reuse fakes (e.g., integration tests)
Related Documentation
core/testing/README.md— Detailed usage and API referenceAGENTS.md§ 3B — Testing rules and KMP purity.github/copilot-instructions.md— Build commandsdocs/kmp-status.md— KMP module status