A failing UI assertion often shows what the test saw, but not what the app logged while the simulator handled the tap, request, or navigation. A scoped iOS Simulator unified-log capture gives the app messages for the same run window so a login, deep link, permission, or network failure can be matched to app-side behavior.

xcrun simctl spawn booted runs the macOS log tool inside the booted simulator. Filtering by the app's OSLog subsystem keeps the file small enough to review beside the .xcresult bundle instead of collecting every SpringBoard and system daemon message.

Start the log stream before the target UI test, let the stream stop after a fixed timeout, then compare the saved lines with the failing test in Xcode. A physical iPhone or iPad uses Xcode's device console or another device-log collector; the simulator command path is for local or CI-style simulator runs with full Xcode selected.

Steps to capture XCUITest simulator device logs:

  1. Open a terminal in the project root and create a directory for test evidence.
    $ mkdir -p TestResults
  2. Start a scoped simulator log stream in a separate terminal before launching the UI test.
    $ xcrun simctl spawn booted log stream \
      --style compact \
      --level info \
      --timeout 12m \
      --predicate 'subsystem == "com.example.MyApp"' \
      > TestResults/LoginUITests-device.log

    Replace com.example.MyApp with the app's Logger or OSLog subsystem. For older NSLog-only apps, use --process MyApp instead of the predicate after the app has launched.

  3. Run the failing or suspicious UI test while the log stream is active.
    $ xcodebuild test \
      -workspace MyApp.xcworkspace \
      -scheme MyApp \
      -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' \
      -only-testing:MyAppUITests/LoginUITests/testValidLogin \
      -resultBundlePath TestResults/LoginUITests.xcresult
    Test Suite 'Selected tests' started.
    Test Case '-[MyAppUITests.LoginUITests testValidLogin]' started.
    Test Case '-[MyAppUITests.LoginUITests testValidLogin]' failed (5.812 seconds).
    ** TEST FAILED **

    Use -project MyApp.xcodeproj instead of -workspace MyApp.xcworkspace for a standalone project. Remove -only-testing:MyAppUITests/LoginUITests/testValidLogin when the whole UI test bundle should run.

  4. Stop the log stream after the test finishes if it has not reached its timeout.

    --timeout 12m prevents a forgotten stream from running indefinitely. Increase it only when the selected test normally runs longer.

  5. Check that the saved log contains messages from the app during the test window.
    $ cat TestResults/LoginUITests-device.log
    Timestamp                Type   Process[PID]   Message
    2026-06-26 09:41:11.846  Info   MyApp[1842]    [Login] Login button tapped
    2026-06-26 09:41:12.431  Error  MyApp[1842]    [Network] POST /session returned 401
    2026-06-26 09:41:12.770  Info   MyApp[1842]    [Login] Showing invalid credentials message

    If the file is empty, the predicate is too narrow, the simulator was not booted, or the stream started after the app exited. Re-run with the app's process name or a broader subsystem filter before collecting unrelated system logs.

  6. Open the result bundle and match the failed test row to the saved log window.
    $ open TestResults/LoginUITests.xcresult

    In Xcode, select the failed test, inspect the failure screenshot or activity timeline, and keep TestResults/LoginUITests-device.log with the .xcresult bundle when filing a bug or CI artifact.
    Related: How to save XCUITest result bundles