Use https://wearables.developer.meta.com/docs/develop/dat/testing-mdk-ios/, then use the Wearables MCP endpoint https://mcp.developer.meta.com/wearables to call search_dat_docs for current iOS Mock Device Kit test guidance. Inspect my iOS tests first, then add the smallest XCTest or XCUITest coverage for mock device pairing, permission setup, camera feed or captured photo behavior, and cleanup. Keep the test deterministic and run the relevant local test command.
import XCTest
import MetaWearablesDAT
@MainActor
class MockDeviceKitTestCase: XCTestCase {
override func setUp() async throws {
try await super.setUp()
try? Wearables.configure()
MockDeviceKit.shared.enable()
}
override func tearDown() async throws {
MockDeviceKit.shared.disable()
try await super.tearDown()
}
}
let device = try MockDeviceKit.shared.pairGlasses(model: .rayBanMeta) let camera = device.services.camera camera.setCameraFeed(fileURL: videoURL)
let device = try MockDeviceKit.shared.pairGlasses(model: .rayBanMeta) let camera = device.services.camera camera.setCapturedImage(fileURL: imageURL)
Note: For more examples of how to leverage the MockDevice Test Server to test your apps, see the Camera Access sample code atExternalSampleApps/CameraAccess/CameraAccessUITests/.
/tmp directory on the simulator.┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ App Process (DEBUG) │ HTTP (localhost) │ XCUITest Process │ │ │ │ │ │ MockDeviceKit │ POST /device/pair │ MockDeviceTestClient │ │ └─ startTestServer() │ POST /device/don │ │ │ │ POST /device/doff │ Port discovery: │ │ │ POST /device/power-on │ reads port from temp file │ │ │ GET /device/state │ written by server on start │ │ │ POST /camera/set-feed │ │ │ │ ... │ │ │ │◄────────────────────────│ │ └─────────────────────────────────────┘ └──────────────────────────────────┘
--ui-testing flag. The server should only be enabled in DEBUG builds.import MWDATMockDevice
if ProcessInfo.processInfo.arguments.contains("--ui-testing") {
MockDeviceKit.shared.enable(config: MockDeviceKitConfig(initiallyRegistered: false))
let portFilePath = ProcessInfo.processInfo.environment["MWDAT_TEST_SERVER_PORT_FILE"]
Task {
try await MockDeviceKit.shared.startTestServer(portFilePath: portFilePath)
// Server is now listening — tests drive mock device setup via HTTP
}
}
MWDATMockDeviceTestClient in your UI test target. The client reads the port from the temp file.import MWDATMockDeviceTestClient
import XCTest
final class MyUITests: XCTestCase {
var portFilePath: String {
NSTemporaryDirectory() + "mwdat_test_server_port.txt"
}
private let app = XCUIApplication()
private var mockClient: MockDeviceTestClient!
private var deviceId: String?
override func setUpWithError() throws {
// Remove any stale port file from a previous run
try? FileManager.default.removeItem(atPath: portFilePath)
app.launchArguments = ["--ui-testing"]
app.launchEnvironment["MWDAT_TEST_SERVER_PORT_FILE"] = portFilePath
app.launch()
// Initialize the client after launch so the server has time to write the port file
mockClient = MockDeviceTestClient(portFilePath: portFilePath)
XCTAssertTrue(mockClient.waitForServer(timeout: 10), "Test server should be running")
}
override func tearDownWithError() throws {
if let deviceId {
mockClient.unpairDevice(deviceId: deviceId)
}
deviceId = nil
}
func testStreaming() {
// Pair a device — pairDevice() powers it on and dons it automatically
guard let id = mockClient.pairDevice() else {
XCTFail("Failed to pair mock device")
return
}
deviceId = id
// Configure camera resources for this device
mockClient.setCameraFeed(deviceId: id, resourceName: "plant", ext: "mp4")
mockClient.setCapturedImage(deviceId: id, resourceName: "plant", ext: "png")
// Device is now paired, powered on, and donned
let startButton = app.buttons["Start streaming"]
XCTAssertTrue(startButton.waitForExistence(timeout: 15))
// Control device state mid-test
mockClient.doff(deviceId: id) // device becomes inactive
mockClient.don(deviceId: id) // device becomes active again
mockClient.fold(deviceId: id) // hinges close, streaming stops
mockClient.unfold(deviceId: id) // hinges open
// Query device state
let state = mockClient.getDeviceState()
XCTAssertEqual(state?["pairedDeviceCount"] as? Int, 1)
}
}
| Method | Description |
|---|---|
pairDevice() | Pairs a mock Ray-Ban Meta, powers on, dons; returns the device ID (nil on failure) |
unpairDevice(deviceId:) | Unpairs the specified mock device |
powerOn(deviceId:) / powerOff(deviceId:) | Controls device power state |
don(deviceId:) / doff(deviceId:) | Simulates wearing / removing the device |
fold(deviceId:) / unfold(deviceId:) | Simulates folding / unfolding the glasses |
captouchTap(deviceId:) | Simulates a single tap gesture (toggles pause/resume) |
captouchTapAndHold(deviceId:) | Simulates tap-and-hold (stops active session) |
setCameraFeed(deviceId:resourceName:ext:) | Sets the camera feed video resource from the test bundle |
setCapturedImage(deviceId:resourceName:ext:) | Sets the captured image resource from the test bundle |
getDeviceState() | Returns {"pairedDeviceCount": Int, "deviceIds": [String]} |
healthCheck() | Checks if the server is reachable |
waitForServer(timeout:) | Polls until the server responds or timeout expires |
MWDATMockDeviceTestClient as a dependency of your UI test target. The client has no dependency on MWDATMockDevice — it communicates purely over HTTP.