Files
Meshtastic-Android/docs/en/developer/testing.md
James Rich 8346b18cc4 docs: veracity pass, screenshot enrichment, and screenshot pipeline split
Audit the user docs for accuracy against the code, enrich them with
component-level screenshots, and separate the doc-screenshot generation
path from the visual-regression gate so doc framing no longer churns test
baselines.

Veracity fixes (claims verified against code):
- connections: removed 3 screenshots that were from the unrelated mPWRD/nymea
  WiFi-provisioning app and rewrote the TCP/IP section to match the real
  Network transport flow (mDNS scan + manual IP:4403); replaced the BLE
  "scan" image (it was the wifi-provision splash) with the real device list.
- nodes: online window is 2h (not 15min); binary online/offline, no "away" tier.
- map: markers are identity-colored node chips, not online-status colors.
- node-metrics & signal-meter: signal quality is preset-relative SNR, not
  fixed thresholds.
- messages: max message length is 200 bytes (not 237/230).
- telemetry: CO2 bands aligned to Co2Severity (Good/Stuffy/Poor/Unsafe/Evacuate).
- translate: locale dirs use {lang}-r{REGION}.

New pages: Home Screen Widget, Help & In-App Docs (Chirpy on-device AI).

Screenshot enrichment + tighter framing: added IAQ scale, firmware verifying,
TAK local server, quick-chat dialog; cropped firmware states and connections
panes to component-level views instead of full-screen frames.

Pipeline split (new :docs-screenshots module, generate-only, not CI-gated):
holds doc-framed compositions so reframing a doc image never moves a regression
baseline; :screenshot-tests stays the gate. copyDocsScreenshots aggregates
both modules. Updated CI filter, governance advisories, dev docs, and the
testing-ci skill.

Translated docs re-sync from the English source via the scheduled Crowdin job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:46:32 -05:00

144 lines
4.5 KiB
Markdown

---
title: Testing
parent: Developer Guide
nav_order: 7
last_updated: 2026-06-11
aliases:
- tests
- unit-tests
- screenshot-tests
---
# Testing
Testing strategy and practices for the Meshtastic KMP project.
## Test Categories
### KMP Unit Tests (`commonTest`)
Shared tests that run on all platforms:
```bash
./gradlew allTests
```
- Business logic tests
- Data model validation
- Search/ranking algorithm tests
- Route serialization tests
### Android Host Tests
Android-specific tests that run on JVM:
```bash
./gradlew test
```
- ViewModel tests
- Repository tests with Room fakes
- Android-specific integration tests
### Compose UI Tests
Compose Multiplatform UI test framework:
```kotlin
@Test
fun myScreenTest() = runComposeUiTest {
setContent { MyScreen() }
onNodeWithText("Expected").assertIsDisplayed()
}
```
Located in `commonTest` or `jvmTest` source sets.
### Screenshot Tests
Uses Android Gradle Plugin's native (layoutlib) screenshot testing framework, split across two modules:
- **`:screenshot-tests`** — the **visual-regression gate**. CI runs `validateDebugScreenshotTest` on it; reframing one of these baselines is a real diff to review. Holds atomic, dual-purpose components.
- **`:docs-screenshots`** — **generate-only**, *not* validated in CI. Holds doc-framed compositions whose framing is tuned for the docs site, so reframing a doc image never churns the regression gate.
```bash
./gradlew :screenshot-tests:updateDebugScreenshotTest # record regression goldens
./gradlew :screenshot-tests:validateDebugScreenshotTest # compare against goldens (CI gate)
./gradlew :docs-screenshots:updateDebugScreenshotTest # record doc-framed composition images
./gradlew :screenshot-tests:copyDocsScreenshots # copy doc images from BOTH modules into docs/assets
```
Rendering is host-deterministic here (layoutlib): a local `update` produces references byte-identical to CI, so locally-recorded goldens pass `validate`. See `docs/assets/screenshots/README.md` for which module a new screenshot belongs in.
### Baseline Profile / Startup Performance
The `:baselineprofile` module (#5735) generates a [Baseline Profile](https://developer.android.com/topic/performance/baselineprofiles/overview) for `:androidApp`, AOT-compiling the hot startup paths so ART doesn't pay the JIT cost on first launch. It targets the **google** flavor (the variant most users run).
The Macrobenchmark generator (`BaselineProfileGenerator`) and the before/after benchmark (`StartupBenchmark`) live in `baselineprofile/src/main/kotlin/org/meshtastic/baselineprofile/`. Both run on a device/emulator:
```bash
./gradlew :androidApp:generateGoogleReleaseBaselineProfile # Generate the profile (commit the output)
./gradlew :androidApp:benchmarkGoogleReleaseBaselineProfile # Quantify the cold-start win
```
The generated profile is merged into `androidApp/src/google/generated/baselineProfiles/` and packaged into release builds via `androidx.profileinstaller`.
> ⚠️ **Warning:** The journey currently covers cold start only (launch → first frame), because CI has no paired radio. Post-connection screens (node list, map, message thread) are not yet AOT-compiled; extend the journey once a fake transport or connected device is wired into the harness.
## Test Organization
```
feature/my-feature/src/
├── commonTest/kotlin/org/meshtastic/feature/myfeature/
│ ├── MyBusinessLogicTest.kt
│ └── MyModelTest.kt
└── jvmTest/kotlin/org/meshtastic/feature/myfeature/
└── MyDesktopSpecificTest.kt
```
## Testing Guidelines
### DO
- Write tests in `commonTest` when possible (runs everywhere)
- Test business logic independently from UI
- Use fakes/stubs instead of mocks where practical
- Test edge cases: empty states, error states, boundary values
- Test deep link routing in `DeepLinkRouterTest`
- Keep tests fast — no network, no disk I/O in unit tests
### DON'T
- Don't test framework behavior (Compose internals, Room queries)
- Don't create tests that depend on other feature modules
- Don't use `Thread.sleep` — use coroutine test dispatchers
- Don't rely on test execution order
## Running Tests
```bash
# All KMP tests
./gradlew allTests
# Specific module
./gradlew :feature:docs:allTests
# Code quality
./gradlew spotlessCheck detekt
# Full verification
./gradlew spotlessCheck detekt kmpSmokeCompile test allTests
```
## CI Integration
Tests run automatically on:
- Pull request creation/update
- Push to `main`
- Pre-release validation
The CI workflow uses `ubuntu-24.04` with JDK 21 and Gradle caching.
---