PATTERN Cited by 1 source
PR-deployed renderer testing in debug app¶
Problem¶
A demo harness for SDUI (like Appcraft Browser) gives you a fast inner loop for renderer development — but it deliberately omits:
- App-shell context (top-level navigation, tab bars, persistent UI).
- Real authentication.
- Real analytics / tracking SDKs.
- Real feature flags.
- Real peer-screen interactions (opening other screens, modal stacks, deep-link resolution).
So a renderer that looks fine in the harness might break in the real app. You need an integration-loop testing path that's still fast enough to use per-PR but runs the renderer in production-app context.
Pattern¶
Use the app's debug build as a "pin a server-side PR and exercise it" harness:
- Developer opens a PR with renderer changes.
- CI deploys the renderer branch to a staging environment — the production app is configured to be able to reach staging renderers by their PR number (usually via a header or query param that routes to the PR-specific deploy).
- Developer launches the debug build of the real Zalando app on a simulator / device.
- Developer enters the PR number in the debug app's settings screen.
- The debug app sets whatever header / routing config is needed so its server calls hit the PR's renderer.
- Developer navigates through the real app and exercises the PR's renderer in full production context.
The cost is:
- ~1 PR-deploy cycle latency (staging deploy = minutes).
- ~1 debug-app install (once per device).
- ~1 config tap (enter PR number).
Appcraft's implementation¶
Appcraft uses this pattern after the Appcraft Browser inner loop (Source: sources/2024-05-15-zalando-transitioning-to-appcraft-evolution-of-zalandos-server-driven-ui-framework):
"After the development stage, web developers open a PR which allows them to deploy the rendering changes in a staging environment, changes are then validated in a debug version of the Zalando app by incorporating the deployed PR number into the app debug settings. This allows testing in production screens and the actual app environment."
Testing-surface pairing¶
The post names both inner + outer loop explicitly:
| Loop | Tool | Fidelity | Latency |
|---|---|---|---|
| Inner | Appcraft Browser | Isolated runtime | Seconds |
| Outer | PR-deployed debug-app | Full app context | Minutes |
| Production | Real deploy behind feature flag | Full fleet | Hours+ |
All three are complementary; each catches a different class of bug.
Why PR number as the routing key¶
- Unambiguous — each PR has exactly one staging deploy.
- Traceable — the PR number in the app's behaviour maps directly to code review; no out-of-band note needed.
- Parallel-safe — multiple developers each pin their own PR without conflict.
- Disposable — merging or closing the PR tears down the staging deploy; the app falls back to production on next launch.
Implementation concerns¶
Staging infrastructure¶
You need per-PR staging deployments. This is often built as:
- CI builds a Docker image per PR.
- Deploys it to a Kubernetes namespace keyed by PR number.
- Exposes a URL like
pr-12345.appcraft-staging.zalando.com. - A load balancer or DNS trick routes the PR number to the right namespace.
Debug-build routing hook¶
The debug build needs:
- A settings UI to enter a PR number.
- Logic to rewrite outgoing API base URLs (or add a header) so relevant calls go to the PR's staging deploy.
- Ideally, a visible indicator that "I am pinned to PR #12345" so the developer doesn't accidentally demo the dev build to someone assuming it's production.
Security / data¶
PR-staging environments should use non-production data where possible. Reaching out to production backends from a PR deploy is a common foot-gun.
Adjacent patterns¶
- Per-PR-ephemeral-environment pattern (also seen in Zalando's Airflow context as patterns/per-pr-airflow-environment-via-dag-versioning) — same idea at a different substrate.
- Canary / feature-flag routing — production-only equivalent: same routing-by-ID idea but the ID is a user cohort or feature flag rather than a PR.
- Appcraft Browser itself is the inner-loop counterpart.
Anti-patterns¶
- Only testing in Appcraft Browser — misses app-shell / integration bugs.
- Only testing via full App-Store releases — eliminates same-day delivery capability.
- Requiring a production deploy to test — reintroduces the release-bottleneck this architecture is designed to avoid.
- No visible indicator of PR-pinning — stakeholder demos look like the PR's behaviour is already in production.
Seen in¶
- sources/2024-05-15-zalando-transitioning-to-appcraft-evolution-of-zalandos-server-driven-ui-framework — the post's described end-to-end testing flow. Paired with Appcraft Browser for a complete dev/test surface coverage.