| name | android-instrumented-tests |
| description | Run this repo's Android test layers and capture device logs. Covers the `scripts/run-instrumented-tests.sh` runner (single-class filter, --skip-build, --unit-only), the underlying `:comapeo-core-react-native:connectedDebugAndroidTest` Gradle task on the integration app, where the JVM/instrumented/service-lifecycle tests live, the report paths, and how to read logcat for the Kotlin (`ComapeoCore`) and embedded-Node (`Comapeo:NodeJS`) tags including the `:ComapeoCore` foreground-service process. Use when running, filtering, or debugging Android unit/instrumented/androidTest runs, a single Android test class, `connectedDebugAndroidTest`, or `adb logcat` for this project. |
Android instrumented tests + log capture
Test layers (see docs/TESTING.md for the full picture)
| Layer | Where | Needs a device? |
|---|
| JVM unit (JUnit4) | android/src/test/java/com/comapeo/core/ | no |
| Instrumented IPC/file-watch (AndroidJUnit4) | android/src/androidTest/java/com/comapeo/core/ | yes |
| Service-lifecycle integration (AndroidJUnit4 on the integration app) | apps/integration/tests/android/ (e.g. ServiceLifecycleTest.kt, ShutdownPathTest.kt) — injected into the prebuilt apps/integration/android/ by the with-android-tests config plugin | yes |
Instrumented/service tests run against the integration app
(com.comapeo.core.integration); the backend runs in its
com.comapeo.core.integration:ComapeoCore foreground-service process.
Running
Use Node 24 (pinned in .nvmrc) — select it with whatever version manager you
use (nvm use, fnm use, asdf, …) or have it on PATH.
npm run test:android:unit
npm run test:android
./scripts/run-instrumented-tests.sh --class NodeJSIPCTest
./scripts/run-instrumented-tests.sh --skip-build
./scripts/run-instrumented-tests.sh --unit-only
The runner: ensures deps → expo prebuild --platform android --no-install (the
with-android-tests plugin re-injects test sources) → boots an emulator if no
device is attached → runs
./gradlew :comapeo-core-react-native:connectedDebugAndroidTest from
apps/integration/android (with
-Pandroid.testInstrumentationRunnerArguments.class=com.comapeo.core.<Class>
when --class is given) → then the JVM unit tests.
Device note: when no device is attached the runner auto-boots
emulator -list-avds | head -1 — the alphabetically-first AVD, which may not be
the API level you want. Boot the AVD you intend to test against before running
(emulator -avd <name> & adb wait-for-device) and the runner will use it.
To run a Gradle task directly (e.g. iterating without the prebuild step), cd apps/integration/android and invoke ./gradlew :comapeo-core-react-native:<task>.
Reports
- Instrumented:
apps/integration/android/build/reports/androidTests/connected/
- JVM unit:
android/build/reports/tests/
Reading logs
Two tags matter (android/src/main/java/com/comapeo/core/log.kt,
android/src/main/cpp/log.cpp):
ComapeoCore — Kotlin native layer (module, service, IPC, process guard).
Comapeo:NodeJS — the embedded Node process's stdout/stderr, bridged to
logcat by the JNI layer. This is where backend errors, dlopen failures, and JS
stack traces surface.
adb logcat -c
adb logcat -s ComapeoCore Comapeo:NodeJS
adb logcat --pid "$(adb shell pidof -s com.comapeo.core.integration:ComapeoCore)"
If pidof returns nothing, the FGS process hasn't started (or already exited) —
check the ComapeoCore tag for the lifecycle transition
(STOPPED → STARTING → STARTED) and whether startForeground was reached.
Gotchas
- The instrumented suite is slow; CI runs it only in the merge queue (or with the
run-e2e label). docs/TESTING.md §5 has the decision table.
apps/integration/android/ and ios/ are gitignored and regenerated by
prebuild — never edit them directly; edit the source under
apps/integration/tests/android/ and the with-android-tests plugin.
- For FGS cold-start latency/ANR work, benchmark a release build (e.g.
assembleRelease) — a debug startForeground is ~10× slower (measured ~4.18 s
debug vs ~434 ms release), so debug timings overstate the ANR risk.