XCUITest: چیست، اصول کار و تست UI iOS

نویسنده: IT Sectr منتشر شده: 2026-04-09 زمان مطالعه: 8 دقیقه

XCUITest یک فریم‌ورک اپل برای تست UI برنامه‌های iOS، iPadOS و macOS است که مستقیماً در XCTest و Xcode تعبیه شده است. این فریم‌ورک امکان شبیه‌سازی اقدامات کاربر را فراهم می‌کند: کلیک‌ها، ورود متن، سوایپ، اسکرول و ژست‌ها — با دسترسی به وضعیت داخلی عناصر رابط. طبق Apple Developer Documentation, 2025، XCUIApplication نقطه ورود برای تمام تست‌های UI است و دسترسی به سلسله‌مراتب عناصر صفحه را فراهم می‌کند.

نکات کلیدی

  • XCUITest — فریم‌ورک بومی اپل برای تست UI، تعبیه‌شده در Xcode
  • رویکرد white-box دسترسی به ویژگی‌های Accessibility و سلسله‌مراتب عناصر را فراهم می‌کند
  • تست‌ها به زبان Swift یا Objective-C در یکپارچگی با XCTest نوشته می‌شوند
  • ضبط تست‌ها از طریق ریکوردر داخلی Xcode در دسترس است
  • اجرا روی شبیه‌ساز iOS یا دستگاه واقعی بدون سرورهای اضافی انجام می‌شود

XCUITest چیست

XCUITest یک فریم‌ورک تست UI است که توسط اپل در Xcode 7 (سال 2015) منتشر شد. این فریم‌ورک جایگزین UI Automation (UIA) شد و به ابزار استاندارد برای تست خودکار رابط کاربری در پلتفرم‌های اپل تبدیل گردید. XCUITest کاملاً در XCTest — فریم‌ورک تست یکپارچه اپل — ادغام شده است.

تفاوت با تست‌های واحد 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) است. عناصر از طریق زنجیره‌های Query در سلسله‌مراتب سازماندهی می‌شوند: app.buttons[].staticTexts[].tables[]. این امکان یافتن انعطاف‌پذیر هر عنصر را روی صفحه فراهم می‌کند.

Accessibility و مکان‌یاب‌ها

XCUITest از ویژگی‌های Accessibility برای شناسایی عناصر استفاده می‌کند: accessibilityIdentifier — شناسه برنامه‌نویسی، و accessibilityLabel — توضیحات برای VoiceOver. توصیه می‌شود accessibilityIdentifier را در کد برنامه تنظیم کنید — این کار تست‌ها را مستقل از بومی‌سازی و چیدمان پایدار می‌کند.

نوشتن تست‌های UI در XCUITest

تست‌های 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 پشتیبانی می‌کند. به عنوان مثال، انتظار برای ظاهر شدن عنصر در عرض ۵ ثانیه: 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 با مختصات و مدت زمان دلخواه استفاده می‌شود. این امکان تست ژست‌های سفارشی مانند نقاشی یا drag-and-drop را فراهم می‌کند.

ره‌گیری درخواست‌های شبکه

از Xcode 12، XCUITest از ره‌گیری درخواست‌های شبکه از طریق XCTestExpectation و URLProtocol پشتیبانی می‌کند. این امکان تست برنامه در حالت آفلاین یا با پاسخ‌های سرور جعلی بدون تغییر کد برنامه را فراهم می‌کند.

XCUITest در CI/CD

XCUITest در محیط‌های CI از طریق xcodebuild با پرچم test اجرا می‌شود. برای اجرای موازی روی چندین شبیه‌ساز از xcodebuild -testPlan با پیکربندی اجرای موازی در طرح Xcode استفاده می‌شود. GitHub Actions، Bitrise و Jenkins پشتیبانی داخلی از XCUITest دارند.

پیکربندی برای CI

برای CI نیاز به تنظیم code signing، provisioning profiles و تعیین مقصد (شبیه‌ساز یا دستگاه) است. تست‌های iOS روی شبیه‌ساز به گواهی نیاز ندارند. برای دستگاه‌های واقعی امضای خودکار از طریق Xcode Cloud یا Fastlane لازم است.

bash
# اجرای 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

تست Accessibility از طریق XCUITest

XCUITest با Accessibility API اپل پیوند نزدیکی دارد، زیرا جستجوی عناصر بر اساس ویژگی‌های دسترس‌پذیری است. تست دسترس‌پذیری — نه تنها یک روش یافتن عناصر، بلکه بررسی دسترس‌پذیری برنامه برای افراد دارای معلولیت است. XCUITest می‌تواند accessibilityLabel، traits و hints را بررسی کند.

بررسی VoiceOver

VoiceOver — صفحه‌خوان اپل برای کاربران نابینا. XCUITest امکان بررسی را فراهم می‌کند: accessibilityLabel — آیا عنصر با متن قابل فهمی توصیف شده است، accessibilityTraits — آیا نوع عنصر مطابقت دارد (دکمه، عنوان، تصویر)، و accessibilityHint — آیا راهنمایی درباره نتیجه اقدام می‌دهد. این بررسی‌ها برای انتشار در App Store الزامی هستند و XCUITest آن‌ها را در چارچوب اجرای رگرسیون خودکار می‌کند.

بررسی خودکار Accessibility

از Xcode 15، XCUITest از بررسی داخلی Accessibility از طریق XCTAttachment با نوع accessibilityAudit پشتیبانی می‌کند. تست به طور خودکار درباره عناصر با کنتراست ناکافی، تصاویر بدون برچسب و traits نادرست گزارش می‌دهد. این جایگزین Accessibility Inspector دستی می‌شود.

swift
// حسابرسی 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

XCUITest از اندازه‌گیری عملکرد UI از طریق XCTOSSignpostMetric و XCUIApplication.metrics پشتیبانی می‌کند. می‌توان زمان راه‌اندازی برنامه (launch time)، سرعت ناوبری، زمان پاسخ به ژست‌ها را اندازه‌گیری کرد. تست‌های عملکرد با اندازه‌گیری baseline اجرا می‌شوند و در صورت تجاوز از آستانه به طور خودکار ناموفق می‌شوند. این امکان جلوگیری از پسرفت‌های عملکرد را قبل از رسیدن به کاربران در نسخه انتشار فراهم می‌کند.

پیکربندی baseline

Baseline — زمان مرجع اجرای تست است. Xcode baseline را برای هر تست در مدل دستگاه خاص و نسخه iOS ذخیره می‌کند. اگر اجرای جدید از baseline به میزان درصد مشخصی (پیش‌فرض ۱۰٪) بیشتر شود، تست ناموفق در نظر گرفته می‌شود. برای به‌روزرسانی baseline از دستور Edit Baseline در گزارش تست استفاده می‌شود. محاسبه مجدد baseline هنگام به‌روزرسانی نسخه iOS یا تغییر مدل دستگاه برای مزرعه CI مهم است.

نظارت بر پایداری تست‌ها

برای ردیابی پایداری تست‌های XCUITest از پرچم‌ها استفاده می‌شود: continueAfterFailure (آیا تست پس از اولین شکست ادامه یابد) و طرح‌های تست Xcode با پیکربندی‌های تکرار. توصیه می‌شود راه‌اندازی مجدد خودکار تست‌های ناموفق (retry) — تا ۳ تلاش برای تست‌های ناپایدار مرتبط با زمان‌بندی انیمیشن‌ها یا تأخیرهای شبکه — پیکربندی شود.

تست اعلان‌های پوش و Deep Links

XCUITest از تست اعلان‌های پوش و Deep Links از طریق springboard و launchArguments پشتیبانی می‌کند. برای اعلان‌های پوش از XCUIApplication().launchArguments با پارامتر -UNUserNotificationCenter و ارسال از طریق XCTest استفاده می‌شود. Deep Links از طریق open URL با تعیین طرح سفارشی تست می‌شوند — XCUITest دیالوگ سیستمی را ره‌گیری می‌کند و بررسی می‌کند که آیا برنامه با صفحه صحیح باز شده است. برای تست سناریوی پاسخ به اعلان از XCUIApplication().springboard استفاده می‌شود که کلیک روی بنر اعلان را در مرکز اعلان‌های iOS شبیه‌سازی می‌کند. این سناریوها برای برنامه‌های دارای دیپ‌لینک و کمپین‌های پوش حیاتی هستند، جایی که بررسی صحت پردازش فراخوانی‌های خارجی ضروری است.

ادغام با Instruments

برای پروفایل‌گیری دقیق عملکرد، XCUITest با Instruments ادغام می‌شود. در طول تست می‌توان پروفایل‌گیری Time Profiler، Core Animation یا Leaks را از طریق XCTMetric اجرا کرد. نتایج پروفایل‌گیری در گزارش ذخیره می‌شوند و برای تحلیل در Xcode در دسترس هستند. این به ویژه برای بهینه‌سازی زمان راه‌اندازی برنامه، ناوبری بین صفحات و عملکرد انیمیشن‌ها — تنگناهای معمولی در برنامه‌های iOS — مفید است.

سوالات متداول

تفاوت بین XCUITest و XCTest چیست؟

XCTest — یک فریم‌ورک عمومی برای تمام انواع تست‌های اپل، شامل تست‌های واحد و تست‌های عملکرد است. XCUITest — یک لایه بالایی بر XCTest برای تست UI است که کلاس‌های XCUIApplication، XCUIElement و XCUIElementQuery را برای تعامل با رابط اضافه می‌کند.

آیا می‌توان از XCUITest با Objective-C استفاده کرد؟

بله، XCUITest از هر دو Swift و Objective-C پشتیبانی می‌کند. با این حال، بیشتر مثال‌ها و مستندات اپل به Swift نوشته شده‌اند. پروژه‌های Objective-C می‌توانند بدون پیکربندی اضافی از XCUITest استفاده کنند — فریم‌ورک از طریق @import XCTest در دسترس است.

XCUITest چگونه عناصر را روی صفحه پیدا می‌کند؟

XCUITest از Accessibility API اپل استفاده می‌کند. عناصر با accessibilityIdentifier، accessibilityLabel، نوع (button، textField، staticText) یا موقعیت در سلسله‌مراتب پیدا می‌شوند. هرچه ویژگی‌های Accessibility در کد برنامه دقیق‌تر تعیین شوند، تست‌ها پایدارتر خواهند بود.

آیا XCUITest از ضبط تست پشتیبانی می‌کند؟

بله، Xcode شامل ریکوردر داخلی تست‌های UI است. هنگام اجرای تست در حالت ضبط، Xcode تمام تعاملات با رابط را ثبت می‌کند و کد Swift تولید می‌کند. کد ضبط شده را می‌توان بهبود بخشید: بررسی‌ها اضافه کرد، به Page Objects منتقل کرد و پارامترسازی نمود.

چگونه XCUITest را روی دستگاه واقعی اجرا کنیم؟

برای اجرا روی دستگاه واقعی باید: دستگاه را به Mac متصل کنید، آن را به Apple Developer Program اضافه کنید، provisioning profile را پیکربندی کنید، برنامه را با گواهی توسعه امضا کنید و دستگاه را به عنوان مقصد در xcodebuild انتخاب کنید.

خلاصه

  • XCUITest — فریم‌ورک بومی اپل برای تست UI برنامه‌های iOS، iPadOS و macOS
  • ادغام با Xcode ضبط تست، اجرای موازی و گزارش‌های داخلی را فراهم می‌کند
  • XCUIApplication و XCUIElement — کلاس‌های کلیدی برای تعامل با برنامه
  • ویژگی‌های Accessibility به عنوان مکان‌یاب‌های قابل اعتماد استفاده می‌شوند که در تغییرات چیدمان پایدارند
  • انتظارها از طریق XCTWaiter و NSPredicate پیاده‌سازی می‌شوند — همگام‌سازی خودکار وجود ندارد
  • CI/CD از طریق xcodebuild با اجرای موازی روی شبیه‌سازها پشتیبانی می‌شود
  • سناریوهای پیشرفته شامل multitouch، Siri Intents، ره‌گیری درخواست‌های شبکه و Deep Links است

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید