XCUITest: khái niệm, cách hoạt động và kiểm thử UI iOS

Tác giả: IT Sectr Đã đăng: 2026-04-09 Thời gian đọc: 8 phút

XCUITest là framework của Apple dành cho kiểm thử UI các ứng dụng iOS, iPadOS và macOS, được tích hợp trực tiếp vào XCTest và Xcode. Nó cho phép mô phỏng các hành động của người dùng: chạm, nhập văn bản, vuốt, cuộn và cử chỉ — với quyền truy cập vào trạng thái bên trong của các phần tử giao diện. Theo Apple Developer Documentation, 2025, XCUIApplication là điểm vào cho tất cả các kiểm thử UI và cung cấp quyền truy cập vào hệ phân cấp các phần tử màn hình.

Các điểm chính

  • XCUITest là framework kiểm thử UI gốc của Apple được tích hợp trong Xcode
  • Phương pháp hộp trắng cung cấp quyền truy cập vào các thuộc tính trợ năng và hệ phân cấp phần tử
  • Các bài kiểm thử được viết bằng Swift hoặc Objective-C tích hợp với XCTest
  • Tính năng ghi lại kiểm thử có sẵn qua trình ghi tích hợp trong Xcode
  • Thực thi diễn ra trên trình mô phỏng iOS hoặc thiết bị thật mà không cần máy chủ bổ sung

XCUITest là gì

XCUITest là framework kiểm thử UI được Apple phát hành trong Xcode 7 (2015). Nó thay thế UI Automation (UIA) và trở thành công cụ tiêu chuẩn cho kiểm thử giao diện tự động trên các nền tảng Apple. XCUITest được tích hợp hoàn toàn vào XCTest — framework kiểm thử thống nhất của Apple.

Khác biệt so với kiểm thử đơn vị XCTest

Không giống kiểm thử đơn vị, vốn kiểm tra logic ở cấp lớp và phương thức, XCUITest kiểm thử giao diện người dùng thông qua mô phỏng hành động. Các kiểm thử chạy trong một tiến trình riêng biệt với ứng dụng và tương tác với nó thông qua API trợ năng — điều này đảm bảo tính cô lập và độ tin cậy.

Lợi ích của phương pháp gốc

XCUITest không yêu cầu cài đặt máy chủ bên thứ ba (khác với Appium) hoặc thư viện bổ sung để tương tác với thiết bị. Mọi thứ cần thiết đã được bao gồm trong Xcode. Điều này đảm bảo khả năng tương thích tốt nhất với các phiên bản iOS mới và truy cập tức thì vào các cử chỉ và điều khiển mới.

Kiến trúc XCUITest và XCTest

Kiến trúc XCUITest được xây dựng trên hai lớp chính: XCUIApplication — ứng dụng có thể kiểm thử được khởi chạy, và XCUIElement — phần tử giao diện. Trình chạy kiểm thử XCTest quản lý vòng đời kiểm thử: setUp, các phương thức kiểm thử, tearDown. XCUITest chạy như một tiến trình riêng điều khiển ứng dụng thông qua cầu nối trợ năng.

Hệ phân cấp phần tử

Mỗi phần tử UI được đại diện bởi một đối tượng XCUIElement, chứa các phương thức để truy vấn trạng thái (exists, isHittable, label, value) và hành động (tap, pressForDuration, swipeUp, typeText). Các phần tử được tổ chức thành hệ phân cấp thông qua các chuỗi truy vấn: app.buttons[].staticTexts[].tables[]. Điều này cho phép tìm kiếm linh hoạt bất kỳ phần tử nào trên màn hình.

Trợ năng và bộ định vị

XCUITest sử dụng các thuộc tính trợ năng để xác định phần tử: accessibilityIdentifier — một định danh lập trình, và accessibilityLabel — mô tả cho VoiceOver. Nên đặt accessibilityIdentifier trong mã ứng dụng — điều này làm cho các kiểm thử ổn định bất kể bản địa hóa và bố cục.

Viết kiểm thử UI với XCUITest

Các kiểm thử XCUITest được viết bằng Swift sử dụng cú pháp XCTest. Mỗi lớp kiểm thử kế thừa từ XCTestCase và chứa các phương thức bắt đầu bằng test. Trong phương thức setUp, ứng dụng được khởi chạy với cấu hình cần thiết, và trong tearDown, việc dọn dẹp và kết thúc phiên làm việc được thực hiện.

Kịch bản kiểm thử cơ bản

Một kiểm thử điển hình: tìm phần tử → thực hiện hành động → xác nhận kết quả. Tìm kiếm phần tử được thực hiện thông qua các truy vấn con XCUIElementQuery: app.buttons["loginButton"], app.textFields["email"]. Hành động: .tap(), .typeText("text"), .swipeUp(). Xác nhận: XCTAssertTrue(element.exists) hoặc 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)
    }
}

Chờ đợi và đồng bộ hóa

XCUITest hỗ trợ chờ đợi rõ ràng thông qua XCTWaiter và các vị từ NSPredicate. Ví dụ, chờ một phần tử xuất hiện trong vòng 5 giây: XCTWaiter().wait(for: [expectation], timeout: 5). Không giống Detox, XCUITest không có đồng bộ hóa tự động với các yêu cầu mạng.

swift
// Chờ phần tử xuất hiện với thời gian chờ
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)

Tính năng nâng cao của XCUITest

XCUITest hỗ trợ kiểm thử các kịch bản phức tạp: cử chỉ đa chạm, thông báo push, Deep Links, SFSafariViewController và tương tác giữa các ứng dụng. Siri Intents cũng có thể được kiểm thử thông qua XCUITest với mô phỏng Siri Remote.

Kiểm thử cử chỉ

XCUITest hỗ trợ tất cả các cử chỉ phổ biến: tap, doubleTap, pressForDuration, swipeUp/Down/Left/Right, pinch, rotate, twoFingerTap. Đối với các kịch bản phức tạp, XCUIGesture được sử dụng với tọa độ và thời lượng tùy chỉnh. Điều này cho phép kiểm thử các cử chỉ tùy chỉnh như vẽ hoặc kéo và thả.

Chặn yêu cầu mạng

Bắt đầu từ Xcode 12, XCUITest hỗ trợ chặn yêu cầu mạng thông qua XCTestExpectation và URLProtocol. Điều này cho phép kiểm thử ứng dụng ở chế độ ngoại tuyến hoặc với phản hồi máy chủ giả định mà không sửa đổi mã ứng dụng.

XCUITest trong CI/CD

XCUITest chạy trong môi trường CI thông qua xcodebuild với cờ test. Để thực thi song song trên nhiều trình mô phỏng, sử dụng xcodebuild -testPlan với cấu hình thực thi song song trong lược đồ Xcode. GitHub Actions, Bitrise và Jenkins có hỗ trợ tích hợp cho XCUITest.

Cấu hình cho CI

Đối với CI, cần cấu hình chữ ký mã, hồ sơ cấp quyền và chỉ định đích đến (trình mô phỏng hoặc thiết bị). Các kiểm thử iOS trên trình mô phỏng không yêu cầu chứng chỉ. Đối với thiết bị thật, cần chữ ký tự động thông qua Xcode Cloud hoặc Fastlane.

bash
# Chạy XCUITest trên trình mô phỏng qua xcodebuild
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

Kiểm thử trợ năng với XCUITest

XCUITest liên kết chặt chẽ với API trợ năng của Apple, vì việc tìm kiếm phần tử dựa trên các thuộc tính trợ năng. Kiểm thử trợ năng không chỉ là cách tìm phần tử mà còn là cách xác minh khả năng tiếp cận ứng dụng cho người khuyết tật. XCUITest có thể kiểm tra accessibilityLabel, traits và hints.

Xác minh VoiceOver

VoiceOver là trình đọc màn hình của Apple dành cho người dùng khiếm thị. XCUITest cho phép kiểm tra: accessibilityLabel — phần tử có được mô tả bằng văn bản rõ ràng không, accessibilityTraits — loại phần tử có khớp không (nút, tiêu đề, hình ảnh), và accessibilityHint — có cung cấp gợi ý về kết quả hành động không. Những kiểm tra này là bắt buộc để xuất bản App Store và XCUITest tự động hóa chúng như một phần của quá trình chạy hồi quy.

Kiểm tra trợ năng tự động

Bắt đầu từ Xcode 15, XCUITest hỗ trợ kiểm tra trợ năng tích hợp thông qua XCTAttachment với loại accessibilityAudit. Kiểm thử tự động báo cáo về các phần tử có độ tương phản không đủ, hình ảnh không có nhãn và traits không chính xác. Điều này thay thế công cụ kiểm tra trợ năng thủ công.

swift
// Kiểm tra trợ năng trong XCUITest
func testAccessibilityAudit() {
    let app = XCUIApplication()
    app.launch()

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

    // Kiểm tra một phần tử cụ thể
    let button = app.buttons["submitButton"]
    XCTAssertTrue(button.label.count > 0)
    XCTAssertTrue(button.isAccessibilityElement)
}

Kiểm thử hiệu suất trong XCUITest

XCUITest hỗ trợ đo lường hiệu suất UI thông qua XCTOSSignpostMetric và XCUIApplication.metrics. Có thể đo thời gian khởi động ứng dụng, tốc độ điều hướng và thời gian phản hồi cử chỉ. Các kiểm thử hiệu suất chạy với đo lường đường cơ sở và tự động thất bại khi vượt quá ngưỡng. Điều này giúp ngăn chặn suy giảm hiệu suất trước khi chúng đến tay người dùng trong bản phát hành.

Cấu hình đường cơ sở

Đường cơ sở (baseline) là thời gian thực thi tham chiếu của một kiểm thử. Xcode ghi nhớ đường cơ sở cho mỗi kiểm thử trên một mô hình thiết bị và phiên bản iOS cụ thể. Nếu một lần chạy mới vượt quá đường cơ sở một tỷ lệ phần trăm nhất định (mặc định 10%), kiểm thử được coi là thất bại. Để cập nhật đường cơ sở, sử dụng lệnh Edit Baseline trong báo cáo kiểm thử. Điều quan trọng là tính lại đường cơ sở khi cập nhật phiên bản iOS hoặc thay đổi mô hình thiết bị cho trang trại CI.

Giám sát ổn định kiểm thử

Để giám sát ổn định của các kiểm thử XCUITest, các cờ được sử dụng: continueAfterFailure (có tiếp tục kiểm thử sau lần thất bại đầu tiên không) và các kế hoạch kiểm thử Xcode với cấu hình thử lại. Nên cấu hình tự động khởi động lại các kiểm thử thất bại (retry) — tối đa 3 lần cho các kiểm thử không ổn định liên quan đến thời gian hoạt ảnh hoặc độ trễ mạng.

Kiểm thử thông báo push và Deep Links

XCUITest hỗ trợ kiểm thử thông báo push và Deep Links thông qua springboard và launchArguments. Đối với thông báo push, sử dụng XCUIApplication().launchArguments với tham số -UNUserNotificationCenter và gửi qua XCTest. Deep Links được kiểm thử qua open URL với lược đồ tùy chỉnh — XCUITest chặn hộp thoại hệ thống và kiểm tra xem ứng dụng có mở đúng màn hình không. Để kiểm thử kịch bản phản hồi thông báo, sử dụng XCUIApplication().springboard, mô phỏng việc chạm vào biểu ngữ thông báo trong trung tâm thông báo iOS. Các kịch bản này rất quan trọng đối với các ứng dụng có deep links và chiến dịch push, nơi cần xác minh việc xử lý chính xác các lời gọi bên ngoài.

Tích hợp với Instruments

Để phân tích hiệu suất chi tiết, XCUITest tích hợp với Instruments. Trong quá trình kiểm thử, có thể khởi chạy phân tích Time Profiler, Core Animation hoặc Leaks thông qua XCTMetric. Kết quả phân tích được lưu trong báo cáo và có sẵn để phân tích trong Xcode. Điều này đặc biệt hữu ích để tối ưu hóa thời gian khởi động ứng dụng, điều hướng giữa các màn hình và hiệu suất hoạt ảnh — các nút cổ chai điển hình trong ứng dụng iOS.

Câu hỏi thường gặp

Sự khác biệt giữa XCUITest và XCTest là gì?

XCTest là framework tổng quát cho tất cả các loại kiểm thử Apple, bao gồm kiểm thử đơn vị và kiểm thử hiệu suất. XCUITest là phần mở rộng trên XCTest dành cho kiểm thử UI, bổ sung các lớp XCUIApplication, XCUIElement và XCUIElementQuery để tương tác với giao diện.

Có thể sử dụng XCUITest với Objective-C không?

Có, XCUITest hỗ trợ cả Swift và Objective-C. Tuy nhiên, hầu hết các ví dụ và tài liệu của Apple được viết bằng Swift. Các dự án Objective-C có thể sử dụng XCUITest mà không cần thiết lập thêm — framework có sẵn thông qua @import XCTest.

XCUITest tìm phần tử trên màn hình như thế nào?

XCUITest sử dụng API trợ năng của Apple. Các phần tử được tìm theo accessibilityIdentifier, accessibilityLabel, loại (button, textField, staticText) hoặc vị trí trong hệ phân cấp. Các thuộc tính trợ năng trong mã ứng dụng càng chính xác thì kiểm thử càng ổn định.

XCUITest có hỗ trợ ghi lại kiểm thử không?

Có, Xcode bao gồm trình ghi kiểm thử UI tích hợp. Khi chạy kiểm thử ở chế độ ghi, Xcode ghi lại tất cả tương tác với giao diện và tạo mã Swift. Mã đã ghi có thể được tinh chỉnh: thêm xác nhận, trích xuất thành Page Objects và tham số hóa.

Làm thế nào để chạy XCUITest trên thiết bị thật?

Để chạy trên thiết bị thật, cần: kết nối thiết bị với Mac, thêm nó vào Apple Developer Program, cấu hình hồ sơ cấp quyền, ký ứng dụng bằng chứng chỉ phát triển và chọn thiết bị làm đích đến trong xcodebuild.

Tổng kết

  • XCUITest là framework kiểm thử UI gốc của Apple cho ứng dụng iOS, iPadOS và macOS
  • Tích hợp Xcode cung cấp tính năng ghi kiểm thử, thực thi song song và báo cáo tích hợp
  • XCUIApplication và XCUIElement là các lớp chính để tương tác với ứng dụng
  • Các thuộc tính trợ năng được sử dụng làm bộ định vị đáng tin cậy, ổn định khi thay đổi bố cục
  • Chờ đợi được thực hiện thông qua XCTWaiter và NSPredicate — không có đồng bộ hóa tự động
  • CI/CD được hỗ trợ thông qua xcodebuild với thực thi song song trên trình mô phỏng
  • Các kịch bản nâng cao bao gồm đa chạm, Siri Intents, chặn yêu cầu mạng và Deep Links

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm