XCUITest:是什么、工作原理及iOS UI测试

作者: IT Sectr 发布日期: 2026-04-09 阅读时间: 8 分钟

XCUITest 是 Apple 用于 iOS、iPadOS 和 macOS 应用 UI 测试的框架,直接内置于 XCTest 和 Xcode 中。它允许模拟用户操作:点击、文本输入、滑动、滚动和手势——并可访问界面元素的内部状态。根据 Apple Developer Documentation, 2025XCUIApplication 是所有 UI 测试的入口点,并提供对屏幕元素层次的访问。

要点

  • XCUITest — Apple 的原生 UI 测试框架,内置于 Xcode
  • 白盒方法 提供对 Accessibility 属性和元素层次的访问
  • 测试 使用 Swift 或 Objective-C 编写,与 XCTest 集成
  • 测试录制 通过 Xcode 内置的录制器可用
  • 运行 在 iOS 模拟器或真实设备上执行,无需额外服务器

什么是 XCUITest

XCUITest 是 Apple 在 Xcode 7(2015 年)中发布的 UI 测试框架。它取代了 UI Automation (UIA),并成为 Apple 平台上自动化界面测试的标准工具。XCUITest 完全集成到 XCTest——Apple 的统一测试框架中。

与 XCTest 单元测试的区别

与在类和方法级别检查逻辑的单元测试不同,XCUITest 通过模拟操作测试用户界面。测试在与应用程序分离的进程中运行,并通过 Accessibility API 与其交互——这确保了隔离性和可靠性。

原生方法的优势

XCUITest 不需要安装第三方服务器(与 Appium 不同)或额外的库来与设备交互。所需的一切都已包含在 Xcode 中。这确保了与新 iOS 版本的最佳兼容性,并立即访问新的手势和控件。

XCUITest 和 XCTest 的架构

XCUITest 的架构基于两个关键类:XCUIApplication — 正在运行的测试应用程序,以及 XCUIElement — 界面元素。XCTest 测试运行器管理测试的生命周期:setUp、测试方法、tearDown。XCUITest 作为独立进程运行,通过 Accessibility 桥控制应用程序。

元素层次结构

每个 UI 元素由 XCUIElement 对象表示,该对象包含用于查询状态(exists、isHittable、label、value)和操作(tap、pressForDuration、swipeUp、typeText)的方法。元素通过查询链组织成层次结构:app.buttons[].staticTexts[].tables[]。这允许灵活地找到屏幕上的任何元素。

Accessibility 和定位器

XCUITest 使用 Accessibility 属性来识别元素:accessibilityIdentifier — 编程标识符,以及 accessibilityLabel — 供 VoiceOver 使用的描述。建议在应用程序代码中设置 accessibilityIdentifier——这使测试独立于本地化和布局而保持稳定。

在 XCUITest 中编写 UI 测试

XCUITest 测试使用 Swift 语言和 XCTest 语法编写。每个测试类继承自 XCTestCase,并包含以 test 开头的方法。在 setUp 方法中,应用程序以所需配置启动,在 tearDown 中进行清理和会话结束。

基本测试场景

典型测试:查找元素 → 执行操作 → 检查结果。元素搜索通过 XCUIElementQuery 子查询进行:app.buttons["loginButton"]、app.textFields["email"]。操作:.tap()、.typeText("text")、.swipeUp()。检查:XCTAssertTrue(element.exists) 或 XCTAssertEqual(element.label, "expected")。

swift
import XCTest

class LoginTests: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        continueAfterFailure = false
        app.launch()
    }

    func testLoginWithValidCredentials() {
        let emailField = app.textFields["emailInput"]
        emailField.tap()
        emailField.typeText("user@test.com")

        let passwordField = app.secureTextFields["passwordInput"]
        passwordField.tap()
        passwordField.typeText("password123")

        app.buttons["loginButton"].tap()

        let homeLabel = app.staticTexts["homeTitle"]
        XCTAssertTrue(homeLabel.exists)
    }
}

等待和同步

XCUITest 通过 XCTWaiter 和 NSPredicate 谓词支持显式等待。例如,在 5 秒内等待元素出现:XCTWaiter().wait(for: [expectation], timeout: 5)。与 Detox 不同,XCUITest 没有与网络请求的自动同步。

swift
// 等待元素出现带超时
let expectedElement = app.staticTexts["welcomeMessage"]
let existsPredicate = NSPredicate(format: "exists == true")
let expectation = XCTNSNotificationExpectation(object: expectedElement)
let result = XCTWaiter().wait(
    for: [expectation], timeout: 5
)
XCTAssertEqual(result, .completed)

XCUITest 的高级功能

XCUITest 支持测试复杂场景:多点触控手势、推送通知、Deep Links、SFSafariViewController 和跨应用交互。Siri 意图也可以通过 XCUITest 使用 Siri Remote 模拟进行测试。

手势测试

XCUITest 支持所有流行手势:tap、doubleTap、pressForDuration、swipeUp/Down/Left/Right、pinch、rotate、twoFingerTap。对于复杂场景,使用具有任意坐标和持续时间的 XCUIGesture。这允许测试自定义手势,如绘图或拖放。

拦截网络请求

从 Xcode 12 开始,XCUITest 通过 XCTestExpectation 和 URLProtocol 支持拦截网络请求。这使得可以在离线模式或使用替换的服务器响应来测试应用程序,而无需修改应用程序代码。

XCUITest 在 CI/CD 中的应用

XCUITest 在 CI 环境中通过 xcodebuild 使用 test 标志运行。要在多个模拟器上并行运行,请使用 xcodebuild -testPlan 并在 Xcode scheme 中配置并行执行。GitHub Actions、Bitrise 和 Jenkins 具有对 XCUITest 的内置支持。

CI 配置

CI 需要配置 code signing、provisioning profiles 并指定目标(模拟器或设备)。模拟器上的 iOS 测试不需要证书。对于真实设备,需要通过 Xcode Cloud 或 Fastlane 进行自动签名

bash
# 通过 xcodebuild 在模拟器上运行 XCUITest
xcodebuild test \
  -project MyApp.xcodeproj \
  -scheme MyApp \
  -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' \
  -resultBundlePath ./TestResults \
  -parallel-testing-enabled YES \
  -parallel-testing-worker-count 4

通过 XCUITest 测试 Accessibility

XCUITest 与 Apple 的 Accessibility API 密切相关,因为元素搜索基于可访问性属性。可访问性测试 — 不仅是查找元素的方法,也是检查应用程序对残障人士的可访问性。XCUITest 可以检查 accessibilityLabel、traits 和 hints。

VoiceOver 检查

VoiceOver — Apple 为盲人用户提供的屏幕阅读器。XCUITest 允许检查:accessibilityLabel — 元素是否用可理解的文本描述,accessibilityTraits — 元素类型是否匹配(按钮、标题、图像),以及 accessibilityHint — 是否提供有关操作结果的提示。这些检查是发布到 App Store 所必需的,XCUITest 在回归运行中自动执行它们。

自动 Accessibility 检查

从 Xcode 15 开始,XCUITest 通过 XCTAttachment 支持内置的 Accessibility 检查,使用 accessibilityAudit 类型。测试会自动报告对比度不足的元素、未标记的图像和错误的 traits。这取代了手动 Accessibility Inspector。

swift
// XCUITest 中的可访问性审核
func testAccessibilityAudit() {
    let app = XCUIApplication()
    app.launch()

    let audit = XCTAttachment(accessibilityAudit: app)
    add(audit)

    // 检查特定元素
    let button = app.buttons["submitButton"]
    XCTAssertTrue(button.label.count > 0)
    XCTAssertTrue(button.isAccessibilityElement)
}

XCUITest 中的性能测试

XCUITest 通过 XCTOSSignpostMetric 和 XCUIApplication.metrics 支持 UI 性能测量。可以测量应用程序启动时间(launch time)、导航速度、对手势的响应时间。性能测试使用基线测量运行,并在超过阈值时自动失败。这可以防止性能回归在发布版本中到达用户之前发生。

基线配置

基线 — 测试执行的参考时间。Xcode 会记住每个测试在特定设备型号和 iOS 版本上的基线。如果新执行超过基线一定百分比(默认为 10%),则测试被视为失败。要更新基线,请使用测试报告中的 Edit Baseline 命令。在更新 iOS 版本或更改 CI 农场的设备型号时,重新计算基线很重要。

测试稳定性监控

用于跟踪 XCUITest 测试稳定性的标志:continueAfterFailure(首次失败后是否继续测试)和带有重试配置的 Xcode 测试计划。建议配置自动重启失败的测试(retry)——对于与动画时间或网络延迟相关的 flaky 测试,最多重试 3 次。

推送通知和 Deep Links 测试

XCUITest 通过 springboard 和 launchArguments 支持推送通知和 Deep Links 测试。对于推送通知,使用带有 -UNUserNotificationCenter 参数的 XCUIApplication().launchArguments 并通过 XCTest 发送。Deep Links 通过使用自定义方案的 open URL 进行测试——XCUITest 拦截系统对话框并检查应用程序是否在正确的屏幕上打开。要测试对通知的响应场景,使用 XCUIApplication().springboard,它模拟在 iOS 通知中心点击通知横幅。这些场景对于具有深层链接和推送活动的应用程序至关重要,需要验证外部调用的正确处理。

与 Instruments 集成

对于详细的性能分析,XCUITest 与 Instruments 集成。在测试期间,可以通过 XCTMetric 启动 Time Profiler、Core Animation 或 Leaks 分析。分析结果保存在报告中,可在 Xcode 中进行分析。这在优化应用程序启动时间、屏幕间导航和动画性能时特别有用——这些是 iOS 应用程序中的典型瓶颈。

常见问题

XCUITest 和 XCTest 有什么区别?

XCTest 是所有 Apple 测试类型的通用框架,包括单元测试和性能测试。XCUITest 是 XCTest 之上的 UI 测试层,它添加了 XCUIApplication、XCUIElement 和 XCUIElementQuery 类用于与界面交互。

XCUITest 可以与 Objective-C 一起使用吗?

可以,XCUITest 同时支持 Swift 和 Objective-C。然而,Apple 的大多数示例和文档都是用 Swift 编写的。Objective-C 项目无需额外配置即可使用 XCUITest——该框架可通过 @import XCTest 访问。

XCUITest 如何找到屏幕上的元素?

XCUITest 使用 Apple 的 Accessibility API。元素通过 accessibilityIdentifier、accessibilityLabel、类型(button、textField、staticText)或层次结构中的位置找到。应用程序代码中设置的 Accessibility 属性越精确,测试就越稳定。

XCUITest 支持测试录制吗?

是的,Xcode 包含用于 UI 测试的内置录制器。在录制模式下运行测试时,Xcode 会记录所有与界面的交互并生成 Swift 代码。录制的代码可以改进:添加检查、提取到 Page Objects 和参数化。

如何在真实设备上运行 XCUITest?

要在真实设备上运行:将设备连接到 Mac,将其添加到 Apple Developer Program,配置 provisioning profile,使用开发证书签署应用程序,并在 xcodebuild 中选择设备作为目标。

总结

  • XCUITest — Apple 用于 iOS、iPadOS 和 macOS 应用 UI 测试的原生框架
  • 与 Xcode 集成 提供测试录制、并行运行和内置报告
  • XCUIApplication 和 XCUIElement — 与应用程序交互的关键类
  • Accessibility 属性 用作可靠的定位器,在布局更改时保持稳定
  • 等待 通过 XCTWaiter 和 NSPredicate 实现 — 没有自动同步
  • CI/CD 通过 xcodebuild 在模拟器上并行运行支持
  • 高级场景 包括多点触控、Siri Intents、网络请求拦截和 Deep Links

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读