Apple's AppIntentsTesting runs an app's own intents with "no mocks, no stubs" and no UI at all; phoneshell's one Shortcuts call is a URL string with no return type
Every tool this site measures drives a phone by pretending to be a finger: tap a point, type into a field, read the screen back. Apple's own AppIntentsTesting framework, shown at WWDC26, skips the finger and the screen entirely by calling an app's intent code directly and checking what comes back. phoneshell's nearest equivalent is a URL string with nothing to check at all.
WWDC26 session 295, "Validate your App Intents adoption with AppIntentsTesting," a roughly 26-minute talk, introduces AppIntentsTesting as a framework for checking an app's App Intents through the same infrastructure Siri, Shortcuts and Spotlight already use to call into it. The session's own description says it lets a developer "execute intents, inspect results, and test entities and queries" without UI automation. Working from a sample calendar app called CometCal, the speaker builds a UI-testing bundle, constructs an IntentDefinitions object from the app's bundle identifier, calls makeIntent with parameters, runs the intent on-device, and asserts on the entity it returns, stating directly that the test runner "executes your App Intents across process boundaries" and receives results "with no mocks, no stubs," and that the tests "don't depend on any UI" at all. The test bundle needs only the target app's bundle identifier, not a copy of its source.
What changed, and when
App Intents itself is not new: Apple has been pushing developers toward it since SiriKit's deprecation was raised at WWDC 2026, and this site has already covered the companion session on onscreen awareness from the same week. What session 295 adds is specifically a testing story, and the gap it closes is concrete. Before AppIntentsTesting, confirming that an app's own App Intents worked meant either driving the UI that exposes them (a Shortcuts run, a Siri request, a Spotlight tap) or writing bespoke unit tests against intent classes directly, with no shared harness and no guarantee either path matched what the system actually does when it calls an intent for real. AppIntentsTesting routes a test through the exact mechanism Siri, Shortcuts and Spotlight use, so passing it is evidence about the real call path, not a proxy for it.
The session also describes a layered testing strategy rather than a single tool: unit-test the fundamental types first, actions, data, and queries, in isolation; then integration-test the deeper system reaches, view annotations, Spotlight indexing, and intents that combine across apps; and still test manually with Siri and Shortcuts on top of both, because AppIntentsTesting validates the intent layer, not the voice or suggestion layer sitting above it.
What phoneshell has instead of an intent layer
phoneshell/apps.py defines an APP_SHORTCUTS table of deeplinks it can fire to skip past UI steps, and exactly one entry in that table touches Apple's own intents system at all: "com.apple.shortcuts": {"run": "shortcuts://run-shortcut?name={name}&input=text&text={text}"}, a URL scheme that asks the Shortcuts app to run a named shortcut with a single text input. It has none of the structure AppIntentsTesting is built around: no typed parameter list, no entity query, and critically, no return value. Firing the URL tells iOS to go run something; whatever that something actually did has to be confirmed the same way every other phoneshell task confirms anything, by reading the screen or the accessibility tree afterward. phoneshell's whole grading model, scoring a task from device state rather than an agent's self-report, exists because it has no other channel into what happened; AppIntentsTesting's whole point is that App Intents give you that other channel for free, a typed value handed back across a process boundary with no screen involved at any point.
| Dimension | AppIntentsTesting | phoneshell | Source |
|---|---|---|---|
| What gets called | The app's own App Intent, via makeIntent | A Shortcuts URL scheme, shortcuts://run-shortcut | WWDC26 session 295; phoneshell/apps.py |
| Parameters | Typed, declared on the intent | Two untyped strings interpolated into a URL | WWDC26 session 295; phoneshell/apps.py |
| Return value | A typed entity, asserted on directly | None; the URL call returns nothing to check | WWDC26 session 295; phoneshell/apps.py |
| How success is confirmed | In-process assertion, same call | A later screenshot or accessibility-tree read, separate step | WWDC26 session 295; phoneshell/bench checks |
| UI involved | None; explicitly stated in the session | Always; it is the only channel phoneshell has | WWDC26 session 295; phoneshell houseFacts |
What it means for anyone grading a phone agent rather than an app's own code
- AppIntentsTesting answers a question phoneshell does not ask: does this app's own intent code behave correctly. phoneshell asks a different one: did an external agent, using only what a person could see and tap, get the phone into the right state. The two are complementary, not competing, but they are easy to conflate because both get called "testing a phone."
- A phone agent benchmark could, in principle, use App Intents as a ground-truth oracle: run the same action through an app's intent to get a typed, verified result, then compare it against what the agent, working blind through the screen, reported or left on screen. phoneshell has no such oracle today; its one Shortcuts call is fire-and-forget, with device-state reads as the only verification that exists.
- The layered strategy the session describes, unit-test the intent, integration-test the system reach, manually test Siri and Shortcuts on top, has no analog in phoneshell's own test design, which grades every one of its 80 tasks at a single layer, the same device-state check, regardless of whether the underlying action was simple or compound.
- Because AppIntentsTesting needs only an app's bundle identifier and runs across a process boundary, it does not require the kind of screen access, accessibility labels, or visual grounding that every tool in this site's "vision versus the accessibility tree" coverage argues about. For whatever slice of an app's behavior is reachable through its own declared intents, that entire argument is moot: there is no screen in the loop to argue about.
Check it yourself
# WWDC26 session 295's own description and chapter list
open "https://developer.apple.com/videos/play/wwdc2026/295"
# community transcript and chapter index:
curl -s https://nonstrict.eu/wwdcindex/wwdc2026/295/ | grep -i "makeIntent\|no mocks\|no UI\|IntentDefinitions"
git clone https://github.com/Blomega/phoneshell && cd phoneshell
grep -n "APP_SHORTCUTS" -A5 phoneshell/apps.py # the one Shortcuts deeplink, and everything it is missing
grep -rn "makeIntent\|IntentDefinitions\|AppIntentsTesting" phoneshell/ || echo "phoneshell has no App Intents test layer"
What would prove this wrong
We claim phoneshell has no channel for confirming an action's result other than reading the screen or accessibility tree afterward. That is wrong the moment any call in phoneshell/apps.py or elsewhere in the repository reads a typed return value from an intent, a Shortcuts run, or any API call rather than inferring success from device state; we found none as of 23 October 2026. We also report AppIntentsTesting as requiring only the target app's bundle identifier, not its source, based on the session's own framing; that is wrong if the full documentation describes additional requirements the 26-minute session omitted, which we will check against Apple's AppIntentsTesting reference pages by 30 April 2027.
Sources
- Apple, Validate your App Intents adoption with AppIntentsTesting, WWDC26 session 295, read 23 October 2026.
- Community transcript and chapter index, nonstrict.eu/wwdcindex/wwdc2026/295, read 23 October 2026.
- Session summary, wwdcnotes.com, read 23 October 2026.
- Blolabel, phoneshell/apps.py,
APP_SHORTCUTS, read 23 October 2026.