XCUITest یک فریمورک اپل برای تست UI برنامههای iOS، iPadOS و macOS است که مستقیماً در XCTest و Xcode تعبیه شده است. این فریمورک امکان شبیهسازی اقدامات کاربر را فراهم میکند: کلیکها، ورود متن، سوایپ، اسکرول و ژستها — با دسترسی به وضعیت داخلی عناصر رابط. طبق Apple Developer Documentation, 2025، XCUIApplication نقطه ورود برای تمام تستهای UI است و دسترسی به سلسلهمراتب عناصر صفحه را فراهم میکند.
نکات کلیدی
XCUITest یک فریمورک تست UI است که توسط اپل در Xcode 7 (سال 2015) منتشر شد. این فریمورک جایگزین UI Automation (UIA) شد و به ابزار استاندارد برای تست خودکار رابط کاربری در پلتفرمهای اپل تبدیل گردید. XCUITest کاملاً در XCTest — فریمورک تست یکپارچه اپل — ادغام شده است.
برخلاف تستهای واحد که منطق را در سطح کلاسها و روشها بررسی میکنند، XCUITest رابط کاربری را از طریق شبیهسازی اقدامات تست میکند. تستها در فرآیندی جداگانه از برنامه اجرا میشوند و از طریق Accessibility API با آن تعامل دارند — این امر ایزولاسیون و قابلیت اطمینان را تضمین میکند.
XCUITest نیازی به نصب سرورهای شخص ثالث (برخلاف Appium) و کتابخانههای اضافی برای تعامل با دستگاه ندارد. همه چیز مورد نیاز قبلاً در Xcode گنجانده شده است. این بهترین سازگاری با نسخههای جدید iOS و دسترسی فوری به ژستها و عناصر کنترلی جدید را فراهم میکند.
معماری XCUITest بر دو کلاس کلیدی استوار است: XCUIApplication — برنامه تحت آزمایش در حال اجرا، و XCUIElement — عنصر رابط. اجراکننده تست XCTest چرخه حیات تستها را مدیریت میکند: setUp، متدهای تست، tearDown. XCUITest به عنوان یک فرآیند جداگانه اجرا میشود که برنامه را از طریق پل Accessibility کنترل میکند.
هر عنصر UI با یک شی XCUIElement نمایش داده میشود که حاوی روشهایی برای پرسوجوی وضعیت (exists, isHittable, label, value) و اقدامات (tap, pressForDuration, swipeUp, typeText) است. عناصر از طریق زنجیرههای Query در سلسلهمراتب سازماندهی میشوند: app.buttons[].staticTexts[].tables[]. این امکان یافتن انعطافپذیر هر عنصر را روی صفحه فراهم میکند.
XCUITest از ویژگیهای Accessibility برای شناسایی عناصر استفاده میکند: 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 پشتیبانی میکند. به عنوان مثال، انتظار برای ظاهر شدن عنصر در عرض ۵ ثانیه: 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 نیز میتوانند از طریق XCUITest با استفاده از شبیهسازی Siri Remote تست شوند.
XCUITest از تمام ژستهای محبوب پشتیبانی میکند: tap، doubleTap، pressForDuration، swipeUp/Down/Left/Right، pinch، rotate، twoFingerTap. برای سناریوهای پیچیده از XCUIGesture با مختصات و مدت زمان دلخواه استفاده میشود. این امکان تست ژستهای سفارشی مانند نقاشی یا drag-and-drop را فراهم میکند.
از Xcode 12، XCUITest از رهگیری درخواستهای شبکه از طریق XCTestExpectation و URLProtocol پشتیبانی میکند. این امکان تست برنامه در حالت آفلاین یا با پاسخهای سرور جعلی بدون تغییر کد برنامه را فراهم میکند.
XCUITest در محیطهای CI از طریق xcodebuild با پرچم test اجرا میشود. برای اجرای موازی روی چندین شبیهساز از xcodebuild -testPlan با پیکربندی اجرای موازی در طرح Xcode استفاده میشود. GitHub Actions، Bitrise و Jenkins پشتیبانی داخلی از XCUITest دارند.
برای CI نیاز به تنظیم code signing، provisioning profiles و تعیین مقصد (شبیهساز یا دستگاه) است. تستهای iOS روی شبیهساز به گواهی نیاز ندارند. برای دستگاههای واقعی امضای خودکار از طریق Xcode Cloud یا Fastlane لازم است.
# اجرای XCUITest روی شبیهساز از طریق 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 اپل پیوند نزدیکی دارد، زیرا جستجوی عناصر بر اساس ویژگیهای دسترسپذیری است. تست دسترسپذیری — نه تنها یک روش یافتن عناصر، بلکه بررسی دسترسپذیری برنامه برای افراد دارای معلولیت است. XCUITest میتواند accessibilityLabel، traits و hints را بررسی کند.
VoiceOver — صفحهخوان اپل برای کاربران نابینا. XCUITest امکان بررسی را فراهم میکند: accessibilityLabel — آیا عنصر با متن قابل فهمی توصیف شده است، accessibilityTraits — آیا نوع عنصر مطابقت دارد (دکمه، عنوان، تصویر)، و accessibilityHint — آیا راهنمایی درباره نتیجه اقدام میدهد. این بررسیها برای انتشار در App Store الزامی هستند و XCUITest آنها را در چارچوب اجرای رگرسیون خودکار میکند.
از Xcode 15، XCUITest از بررسی داخلی Accessibility از طریق XCTAttachment با نوع accessibilityAudit پشتیبانی میکند. تست به طور خودکار درباره عناصر با کنتراست ناکافی، تصاویر بدون برچسب و traits نادرست گزارش میدهد. این جایگزین Accessibility Inspector دستی میشود.
// حسابرسی Accessibility در 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 پشتیبانی میکند. میتوان زمان راهاندازی برنامه (launch time)، سرعت ناوبری، زمان پاسخ به ژستها را اندازهگیری کرد. تستهای عملکرد با اندازهگیری baseline اجرا میشوند و در صورت تجاوز از آستانه به طور خودکار ناموفق میشوند. این امکان جلوگیری از پسرفتهای عملکرد را قبل از رسیدن به کاربران در نسخه انتشار فراهم میکند.
Baseline — زمان مرجع اجرای تست است. Xcode baseline را برای هر تست در مدل دستگاه خاص و نسخه iOS ذخیره میکند. اگر اجرای جدید از baseline به میزان درصد مشخصی (پیشفرض ۱۰٪) بیشتر شود، تست ناموفق در نظر گرفته میشود. برای بهروزرسانی baseline از دستور Edit Baseline در گزارش تست استفاده میشود. محاسبه مجدد baseline هنگام بهروزرسانی نسخه iOS یا تغییر مدل دستگاه برای مزرعه CI مهم است.
برای ردیابی پایداری تستهای XCUITest از پرچمها استفاده میشود: continueAfterFailure (آیا تست پس از اولین شکست ادامه یابد) و طرحهای تست Xcode با پیکربندیهای تکرار. توصیه میشود راهاندازی مجدد خودکار تستهای ناموفق (retry) — تا ۳ تلاش برای تستهای ناپایدار مرتبط با زمانبندی انیمیشنها یا تأخیرهای شبکه — پیکربندی شود.
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 — یک فریمورک عمومی برای تمام انواع تستهای اپل، شامل تستهای واحد و تستهای عملکرد است. XCUITest — یک لایه بالایی بر XCTest برای تست UI است که کلاسهای XCUIApplication، XCUIElement و XCUIElementQuery را برای تعامل با رابط اضافه میکند.
بله، XCUITest از هر دو Swift و Objective-C پشتیبانی میکند. با این حال، بیشتر مثالها و مستندات اپل به Swift نوشته شدهاند. پروژههای Objective-C میتوانند بدون پیکربندی اضافی از XCUITest استفاده کنند — فریمورک از طریق @import XCTest در دسترس است.
XCUITest از Accessibility API اپل استفاده میکند. عناصر با accessibilityIdentifier، accessibilityLabel، نوع (button، textField، staticText) یا موقعیت در سلسلهمراتب پیدا میشوند. هرچه ویژگیهای Accessibility در کد برنامه دقیقتر تعیین شوند، تستها پایدارتر خواهند بود.
بله، Xcode شامل ریکوردر داخلی تستهای UI است. هنگام اجرای تست در حالت ضبط، Xcode تمام تعاملات با رابط را ثبت میکند و کد Swift تولید میکند. کد ضبط شده را میتوان بهبود بخشید: بررسیها اضافه کرد، به Page Objects منتقل کرد و پارامترسازی نمود.
برای اجرا روی دستگاه واقعی باید: دستگاه را به Mac متصل کنید، آن را به Apple Developer Program اضافه کنید، provisioning profile را پیکربندی کنید، برنامه را با گواهی توسعه امضا کنید و دستگاه را به عنوان مقصد در xcodebuild انتخاب کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید