Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2026 AI & Machine Learning

WWDC26 · 26 min · AI & Machine Learning

Validate your App Intents adoption with AppIntentsTesting

Meet AppIntentsTesting, a new framework for validating your App Intents through the same infrastructure used by Siri, Shortcuts, and Spotlight. Discover how to execute intents, inspect results, and test entities and queries — all without requiring UI automation. Find out how to verify integrations like View annotations and Spotlight indexing, helping you catch bugs early in your development workflow.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

  • 0:16 — Introduction
  • 2:01 — Meet CometCal: your first test
  • 2:29 — How AppIntentsTesting works
  • 9:39 — Testing entity queries
  • 13:49 — Combining multiple intents
  • 16:27 — Test-only intents
  • 18:22 — Testing Spotlight indexing
  • 20:56 — Testing view annotations
  • 24:00 — The App Intents testing workflow
  • 25:19 — Next steps

Code shown on screen · 7 snippets

Your first test: execute an intent swift · at 6:48 ↗
import AppIntentsTesting

func testCreateCalendar() async throws {
    let definitions = IntentDefinitions(bundleIdentifier: "com.example.apple-samplecode.CometCal")
    let createCalendar = definitions.intents["CreateCalendarIntent"]
    let result = try await createCalendar.makeIntent(
        name: "Occupy Saturn",
        color: "red"
    ).run()
    XCTAssertEqual(try result.value.title, "Occupy Saturn")
}
Test an entity string query swift · at 12:25 ↗
// Testing Entity string queries
func testEventStringQuery() async throws {
    let results = try await eventEntityDefinition
        .entities(matching: "Cosmic Ray")

    XCTAssertEqual(results.count, 1)
    XCTAssertEqual(try results[0].title, "Cosmic Ray Calibration")
}
Implement the EntityStringQuery under test swift · at 13:00 ↗
// Updated query implementation
struct EventEntityQuery: EntityStringQuery {
    func entities(for identifiers: [EventEntity.ID]) async throws -> [EventEntity] {

    }

    func suggestedEntities() async throws -> [EventEntity] {

    }

    func entities(matching string: String) async throws -> [EventEntity] {
        try calendarManager.fetchEvents()
            .filter { $0.title.localizedCaseInsensitiveContains(string) }
            .map(\.entity)
    }
}
Chain multiple intents in one test swift · at 15:42 ↗
// Test event creation followed by update
func testCreateAndUpdateEvent() async throws {
    let createResult = try await createEventDefinition.makeIntent(
        title: "Asteroid Dodgeball Practice",
        startDate: Date(),
        isAllDay: false,
        calendar: "Deep Space"
    ).run()

    XCTAssertEqual(try createResult.value.title, "Asteroid Dodgeball Practice")

    let updateResult = try await updateEventDefinition.makeIntent(
        title: "Asteroid Dodgeball Rules Overview",
        event: createResult.value
    ).run()

    XCTAssertEqual(try updateResult.value.title, "Asteroid Dodgeball Rules Overview")
}
Make an intent test-only swift · at 17:45 ↗
// Test-only intent: SeedSampleEventsIntent
#if DEBUG
struct SeedSampleEventsIntent: AppIntent {
    static let isDiscoverable = false

    func perform() async throws -> some IntentResult {
        // Create known list of events
        return .result()
    }
}
#endif
Test Spotlight indexing swift · at 20:27 ↗
// Testing Spotlight indexing
func testNewEventIndexedInSpotlight() async throws {

    let before = try await eventEntityDefinition.spotlightQuery("Supernova Viewing Party")
    XCTAssertTrue(before.isEmpty, "Event should not exist in Spotlight yet")

    // ... Create "Supernova Viewing Party" Event

    let after = try await eventEntityDefinition.spotlightQuery("Supernova Viewing Party")
    XCTAssertEqual(after.count, 1)
    XCTAssertEqual(try after[0].title, "Supernova Viewing Party")
}
Test view annotations swift · at 22:33 ↗
/ Testing view annotations
func testEventViewAnnotation() async throws {
    try await openEventDefinition.makeIntent(target: "Morning Launch Briefing").run()

    // Confirm correct event page
    let app = XCUIApplication()
    let title = app.staticTexts["Morning Launch Briefing"]
    XCTAssertTrue(title.waitForExistence(timeout: 5))

    let annotations = try await eventEntityDefinition.viewAnnotations()

    XCTAssertEqual(annotations.count, 1, "Expected exactly one view annotation")
    XCTAssertEqual(try annotations[0].entity.title, "Morning Launch Briefing")
}

Resources