# T25 — the real-ride checklist **This is the only task in the plan that cannot be automated, and it is the one that matters most.** 171 unit and widget tests plus 4 integration tests are green, and none of them prove the app records a ride correctly. Adapted from the native repo's `docs/TESTING.md`, extended for two platforms. --- ## Why a green suite proves nothing here **Neither simulator produces velocity.** `adb emu geo fix` teleports the device and iOS's simulated locations are no better, so every recorded `speedKmh` is `0.0`. That makes the following **structurally unverifiable** without riding: - max speed, average moving speed - moving time (everything sits under the 1.5 km/h noise floor, so it stays 00:00:00) - speed colouring on the map — the whole path renders in one colour - elevation gain against real, *correlated* GPS altitude error - battery over a multi-hour ride - whether iOS suspends a stationary app mid-ride And the subtler trap, which cost v2.0 a release: **when a value cannot change under test, the UI around it cannot be judged either.** Max speed as the headline looked perfectly fine on an emulator where every number was zero. On a real ride it read as a frozen, broken screen. --- ## Before you ride Install both apps. They have different application ids on purpose (`com.rippr` and `com.rippr.port`), so they coexist: ```bash flutter build apk --debug && flutter install # Flutter port adb install -r ~/dojo/samplez/rippr-2.0.1-debug.apk # native reference ``` **Run both simultaneously on the Android ride.** Recording the same ride twice gives a direct numeric comparison, which is far stronger evidence than either app alone. --- ## The ride Do this once on **Android** and once on **iOS**. Pocket the phone — that is the founding use case. | # | Check | Why it is here | |---|---|---| | 1 | Start, pocket, ride ~20 min, stop | The actual usage pattern | | 2 | Max speed plausible against the speedometer | Unverifiable on any simulator | | 3 | Distance plausible against the odometer | Guards the cross-batch anchor | | 4 | Moving time excludes stops | Noise floor behaviour on real data | | 5 | **Elevation gain near zero on flat ground** | The most likely silent bug; synthetic noise is uniform, real error is correlated | | 6 | Pause at a stop, resume — **no straight line across the gap** | The segment guarantee | | 7 | Speed colouring visibly varies along the path | Cannot render in more than one colour on a simulator | | 8 | **A short ride (under 100 m) still shows streets** | The v2.0 zoom bug | | 9 | GPX opens correctly in Google Earth or Strava | Schema-valid is not the same as accepted | | 10 | Battery drain over a multi-hour ride | Never measured, on either app | | 11 | Pause/resume survives a screen-off stretch | Android wake lock, iOS background mode | ### Android only | # | Check | |---|---| | A1 | The ongoing notification appears and persists with the screen off | | A2 | Force-stop the app mid-ride, relaunch — the ride resumes into a **new segment**, and the dead time is **not** added to distance | | A3 | Compare totals against the native app recording the same ride | > **A2 is the fix for a real bug found in the native app.** See T11 in > [PROGRESS.md](PROGRESS.md): the native version measures straight through the dead time, > which a synthetic test showed adding **111 km**. Confirm the port does not. ### iOS only — the genuine unknown | # | Check | |---|---| | I1 | The blue background-location indicator appears while recording | | I2 | Lock the screen for 10 minutes of riding — fixes keep arriving | | I3 | **Park for 15 minutes without stopping the recording, then ride again.** Does recording resume? | | I4 | Take a phone call mid-ride; recording survives | | I5 | Swipe the app away mid-ride — what happens? Document it, whatever it is | **I3 is the decisive test for the whole platform strategy.** If iOS suspends the app when stationary and does not reliably resume, `geolocator` is not sufficient and the `LocationSource` seam exists precisely so `flutter_background_geolocation` (~$500/yr) can be swapped in as one new implementation. Do not make that call without this data. --- ## Recording the results Append findings to [PROGRESS.md](PROGRESS.md) under a T25 heading, including the numbers from both apps where Android was recorded twice. If elevation gain on flat ground is implausible, **do not tune it blind** — the native backlog says so explicitly, and the port's parity harness (`tool/parity/run.sh`) means any change can be checked against the Kotlin implementation first.