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

4.5 KiB

title, parent, nav_order, last_updated, aliases
title parent nav_order last_updated aliases
Testing Developer Guide 7 2026-06-11
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:

./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:

./gradlew test
  • ViewModel tests
  • Repository tests with Room fakes
  • Android-specific integration tests

Compose UI Tests

Compose Multiplatform UI test framework:

@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-screenshotsgenerate-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.
./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 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:

./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

# 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.