XCUITest คือเฟรมเวิร์กของ Apple สำหรับการทดสอบ UI ของแอปพลิเคชัน iOS, iPadOS และ macOS ที่สร้างไว้ใน XCTest และ Xcode โดยตรง ช่วยให้สามารถจำลองการกระทำของผู้ใช้: การแตะ การป้อนข้อความ การปัด การเลื่อน และท่าทาง — พร้อมการเข้าถึงสถานะภายในขององค์ประกอบอินเทอร์เฟซ ตาม Apple Developer Documentation, 2025 XCUIApplication คือจุดเริ่มต้นสำหรับการทดสอบ UI ทั้งหมดและให้การเข้าถึงลำดับชั้นขององค์ประกอบบนหน้าจอ
ประเด็นสำคัญ
XCUITest คือเฟรมเวิร์กการทดสอบ UI ที่เผยแพร่โดย Apple ใน Xcode 7 (ปี 2015) มันแทนที่ UI Automation (UIA) และกลายเป็นเครื่องมือมาตรฐานสำหรับการทดสอบอินเทอร์เฟซอัตโนมัติบนแพลตฟอร์มของ Apple XCUITest ถูกรวมเข้ากับ XCTest อย่างสมบูรณ์ — เฟรมเวิร์กการทดสอบแบบครบวงจรของ Apple
ไม่เหมือนกับการทดสอบหน่วยที่ตรวจสอบตรรกะในระดับคลาสและเมธอด XCUITest จะทดสอบ อินเทอร์เฟซผู้ใช้ ผ่านการจำลองการกระทำ การทดสอบทำงานในกระบวนการที่แยกจากแอปพลิเคชันและโต้ตอบกับมันผ่าน Accessibility API — ซึ่งช่วยให้มั่นใจได้ถึงการแยกส่วนและความน่าเชื่อถือ
XCUITest ไม่จำเป็นต้องติดตั้งเซิร์ฟเวอร์ของบุคคลที่สาม (ต่างจาก Appium) หรือไลบรารีเพิ่มเติมสำหรับการโต้ตอบกับอุปกรณ์ ทุกสิ่งที่จำเป็นมีอยู่ใน Xcode แล้ว ซึ่งช่วยให้มั่นใจได้ถึงความเข้ากันได้ดีที่สุดกับ iOS เวอร์ชันใหม่และการเข้าถึงท่าทางและการควบคุมใหม่ได้ทันที
สถาปัตยกรรมของ XCUITest สร้างขึ้นบนสองคลาสหลัก: XCUIApplication — แอปพลิเคชันที่ทดสอบได้ซึ่งเปิดอยู่ และ XCUIElement — องค์ประกอบอินเทอร์เฟซ ตัวรันการทดสอบ XCTest จะจัดการวงจรชีวิตของการทดสอบ: setUp, เมธอดทดสอบ, tearDown XCUITest ทำงานเป็นกระบวนการแยกที่ควบคุมแอปพลิเคชันผ่านสะพานการช่วยเหลือและการเข้าถึง
แต่ละองค์ประกอบ UI แสดงด้วยออบเจ็กต์ XCUIElement ซึ่งมีเมธอดสำหรับสอบถามสถานะ (exists, isHittable, label, value) และการกระทำ (tap, pressForDuration, swipeUp, typeText) องค์ประกอบถูกจัดระเบียบเป็น ลำดับชั้น ผ่านห่วงโซ่การสอบถาม: app.buttons[].staticTexts[].tables[] ซึ่งช่วยให้ค้นหาองค์ประกอบใดๆ บนหน้าจอได้อย่างยืดหยุ่น
XCUITest ใช้แอตทริบิวต์การช่วยเหลือและการเข้าถึงเพื่อระบุองค์ประกอบ: accessibilityIdentifier — ตัวระบุเชิงโปรแกรม และ accessibilityLabel — คำอธิบายสำหรับ VoiceOver แนะนำให้ตั้งค่า accessibilityIdentifier ในโค้ดของแอปพลิเคชัน — ซึ่งจะทำให้การทดสอบมีความเสถียรโดยไม่ขึ้นกับการแปลภาษาและเลย์เอาต์
การทดสอบ 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")
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 ไม่มีการซิงค์อัตโนมัติกับคำขอเครือข่าย
// รอให้องค์ประกอบปรากฏพร้อมหมดเวลา
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 รองรับการทดสอบสถานการณ์ที่ซับซ้อน: ท่าทางสัมผัสหลายจุด การแจ้งเตือนแบบพุช Deep Links, SFSafariViewController และการโต้ตอบระหว่างแอปพลิเคชัน Siri Intents ก็สามารถทดสอบผ่าน XCUITest ได้โดยใช้การจำลอง Siri Remote
XCUITest รองรับท่าทางยอดนิยมทั้งหมด: tap, doubleTap, pressForDuration, swipeUp/Down/Left/Right, pinch, rotate, twoFingerTap สำหรับสถานการณ์ที่ซับซ้อน จะใช้ XCUIGesture พร้อมพิกัดและระยะเวลาที่กำหนดเอง ซึ่งช่วยให้ทดสอบท่าทางที่กำหนดเอง เช่น การวาดหรือการลากและวาง
เริ่มตั้งแต่ Xcode 12, XCUITest รองรับ การสกัดกั้นคำขอเครือข่าย ผ่าน XCTestExpectation และ URLProtocol ซึ่งช่วยให้ทดสอบแอปพลิเคชันในโหมดออฟไลน์หรือด้วยการตอบสนองของเซิร์ฟเวอร์จำลองโดยไม่ต้องแก้ไขโค้ดแอปพลิเคชัน
XCUITest ทำงานในสภาพแวดล้อม CI ผ่าน xcodebuild ด้วยแฟลก test สำหรับการดำเนินการแบบขนานบนหลาย simulator จะใช้ xcodebuild -testPlan พร้อมการกำหนดค่าการดำเนินการแบบขนานในสคีมาของ Xcode GitHub Actions, Bitrise และ Jenkins มีการสนับสนุนในตัวสำหรับ XCUITest
สำหรับ CI จำเป็นต้องกำหนดค่าการเซ็นชื่อโค้ด โพรไฟล์การจัดเตรียม และระบุปลายทาง (simulator หรืออุปกรณ์) การทดสอบ iOS บน simulator ไม่จำเป็นต้องใช้ใบรับรอง สำหรับอุปกรณ์จริง จำเป็นต้องมี การเซ็นชื่ออัตโนมัติ ผ่าน Xcode Cloud หรือ Fastlane
# รัน XCUITest บน simulator ผ่าน 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
XCUITest เชื่อมโยงอย่างใกล้ชิดกับ Accessibility API ของ Apple เนื่องจากการค้นหาองค์ประกอบขึ้นอยู่กับแอตทริบิวต์การช่วยเหลือและการเข้าถึง การทดสอบการช่วยเหลือและการเข้าถึง ไม่เพียงแต่เป็นวิธีในการค้นหาองค์ประกอบ แต่ยังเป็นวิธีในการตรวจสอบการเข้าถึงแอปพลิเคชันสำหรับผู้ที่มีความพิการอีกด้วย XCUITest สามารถตรวจสอบ accessibilityLabel, traits และ hints
VoiceOver คือโปรแกรมอ่านหน้าจอของ Apple สำหรับผู้ใช้ที่มีความบกพร่องทางการมองเห็น XCUITest ช่วยให้ตรวจสอบ: accessibilityLabel — องค์ประกอบถูกอธิบายด้วยข้อความที่ชัดเจนหรือไม่, accessibilityTraits — ประเภทขององค์ประกอบตรงกันหรือไม่ (ปุ่ม, หัวเรื่อง, รูปภาพ) และ accessibilityHint — ให้คำแนะนำเกี่ยวกับผลลัพธ์ของการกระทำหรือไม่ การตรวจสอบเหล่านี้จำเป็นสำหรับการเผยแพร่ใน App Store และ XCUITest จะทำให้เป็นอัตโนมัติซึ่งเป็นส่วนหนึ่งของการทดสอบการถดถอย
เริ่มตั้งแต่ Xcode 15, XCUITest รองรับการตรวจสอบการช่วยเหลือและการเข้าถึงในตัวผ่าน XCTAttachment ด้วยประเภท accessibilityAudit การทดสอบจะรายงานโดยอัตโนมัติเกี่ยวกับองค์ประกอบที่มีความคมชัดไม่เพียงพอ รูปภาพที่ไม่มีป้ายกำกับ และ traits ที่ไม่ถูกต้อง ซึ่งจะแทนที่ตัวตรวจสอบการช่วยเหลือและการเข้าถึงด้วยตนเอง
// การตรวจสอบการช่วยเหลือและการเข้าถึงใน 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 รองรับการวัดประสิทธิภาพ UI ผ่าน XCTOSSignpostMetric และ XCUIApplication.metrics สามารถวัดเวลาเริ่มต้นแอปพลิเคชัน ความเร็วในการนำทาง และเวลาตอบสนองต่อท่าทาง การทดสอบประสิทธิภาพทำงานด้วยการวัดพื้นฐานและล้มเหลวโดยอัตโนมัติเมื่อเกินเกณฑ์ที่กำหนด ซึ่งช่วยป้องกันประสิทธิภาพลดลงก่อนที่จะถึงผู้ใช้ในบิวด์ที่เผยแพร่
พื้นฐาน (baseline) คือเวลาดำเนินการอ้างอิงของการทดสอบ Xcode จะจดจำพื้นฐานสำหรับแต่ละการทดสอบบนรุ่นอุปกรณ์และเวอร์ชัน iOS ที่เฉพาะเจาะจง หากการรันใหม่เกินพื้นฐานตามเปอร์เซ็นต์ที่กำหนด (ค่าเริ่มต้น 10%) การทดสอบจะถือว่าล้มเหลว ในการอัปเดตพื้นฐาน ให้ใช้คำสั่ง Edit Baseline ในรายงานการทดสอบ สิ่งสำคัญคือต้องคำนวณพื้นฐานใหม่เมื่ออัปเดตเวอร์ชัน iOS หรือเปลี่ยนรุ่นอุปกรณ์สำหรับฟาร์ม CI
สำหรับการตรวจสอบความเสถียรของการทดสอบ XCUITest จะใช้แฟลก: continueAfterFailure (ว่าจะดำเนินการทดสอบต่อหลังจากการล้มเหลวครั้งแรกหรือไม่) และแผนการทดสอบ Xcode พร้อมการกำหนดค่าการลองใหม่ แนะนำให้กำหนดค่าการเริ่มต้นใหม่โดยอัตโนมัติของการทดสอบที่ล้มเหลว (retry) — สูงสุด 3 ครั้งสำหรับการทดสอบที่ไม่เสถียรซึ่งเกี่ยวข้องกับจังหวะเวลาแอนิเมชันหรือความล่าช้าของเครือข่าย
XCUITest รองรับการทดสอบการแจ้งเตือนแบบพุชและ Deep Links ผ่าน springboard และ launchArguments สำหรับการแจ้งเตือนแบบพุช จะใช้ XCUIApplication().launchArguments พร้อมพารามิเตอร์ -UNUserNotificationCenter และการส่งผ่าน XCTest Deep Links ทดสอบผ่าน open URL ด้วยสคีมาที่กำหนดเอง — XCUITest จะสกัดกั้นไดอะล็อกของระบบและตรวจสอบว่าแอปพลิเคชันเปิดด้วยหน้าจอที่ถูกต้องหรือไม่ สำหรับการทดสอบสถานการณ์การตอบสนองต่อการแจ้งเตือน จะใช้ XCUIApplication().springboard ซึ่งจำลองการแตะบนแบนเนอร์การแจ้งเตือนในศูนย์การแจ้งเตือนของ iOS สถานการณ์เหล่านี้มีความสำคัญสำหรับแอปพลิเคชันที่มีดีพลิงก์และแคมเปญพุช ซึ่งจำเป็นต้องตรวจสอบการจัดการการเรียกภายนอกที่ถูกต้อง
สำหรับการสร้างโปรไฟล์ประสิทธิภาพโดยละเอียด XCUITest จะรวมเข้ากับ Instruments ระหว่างการทดสอบ สามารถเริ่มการสร้างโปรไฟล์ Time Profiler, Core Animation หรือ Leaks ผ่าน XCTMetric ได้ ผลลัพธ์การสร้างโปรไฟล์จะถูกบันทึกในรายงานและพร้อมให้วิเคราะห์ใน Xcode ซึ่งมีประโยชน์อย่างยิ่งสำหรับการปรับเวลาเริ่มต้นแอปพลิเคชัน การนำทางระหว่างหน้าจอ และประสิทธิภาพของแอนิเมชัน — จุดคอขวดทั่วไปในแอปพลิเคชัน iOS
คำถามที่พบบ่อย
XCTest คือเฟรมเวิร์กทั่วไปสำหรับการทดสอบ Apple ทุกประเภท รวมถึงการทดสอบหน่วยและการทดสอบประสิทธิภาพ XCUITest คือส่วนขยายเหนือ XCTest สำหรับการทดสอบ UI ที่เพิ่มคลาส XCUIApplication, XCUIElement และ XCUIElementQuery สำหรับการโต้ตอบกับอินเทอร์เฟซ
ได้ XCUITest รองรับทั้ง Swift และ Objective-C อย่างไรก็ตาม ตัวอย่างและเอกสารประกอบของ Apple ส่วนใหญ่เขียนด้วย Swift โปรเจกต์ Objective-C สามารถใช้ XCUITest ได้โดยไม่ต้องตั้งค่าเพิ่มเติม — เฟรมเวิร์กพร้อมใช้งานผ่าน @import XCTest
XCUITest ใช้ Accessibility API ของ Apple องค์ประกอบจะถูกค้นหาตาม accessibilityIdentifier, accessibilityLabel, ประเภท (button, textField, staticText) หรือตำแหน่งในลำดับชั้น ยิ่งแอตทริบิวต์การช่วยเหลือและการเข้าถึงในโค้ดแอปพลิเคชันแม่นยำมากเท่าใด การทดสอบก็จะยิ่งเสถียรมากเท่านั้น
ได้ Xcode มี ตัวบันทึกในตัว สำหรับการทดสอบ UI เมื่อรันการทดสอบในโหมดบันทึก Xcode จะบันทึกการโต้ตอบทั้งหมดกับอินเทอร์เฟซและสร้างโค้ด Swift โค้ดที่บันทึกไว้สามารถปรับปรุงได้: เพิ่มการตรวจสอบ, แยกเป็น Page Objects และกำหนดพารามิเตอร์
ในการรันบนอุปกรณ์จริง จำเป็นต้อง: เชื่อมต่ออุปกรณ์กับ Mac, เพิ่มลงใน Apple Developer Program, กำหนดค่าโพรไฟล์การจัดเตรียม, เซ็นชื่อแอปพลิเคชันด้วยใบรับรองการพัฒนา และเลือกอุปกรณ์เป็นปลายทางใน xcodebuild
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม