تست UI در برنامه‌های موبایل: چیست، انواع و چگونه انجام می‌شود

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

تست UI صحت نمایش و تعامل عناصر رابط کاربری برنامه موبایل — دکمه‌ها، فیلدهای متنی، لیست‌ها و جزء ناوبری را بررسی می‌کند. به عکس تست‌های واحد که منطق کسب و کار را بررسی می‌کنند، تست‌های UI اعمال کاربر را شبیه‌سازی می‌کنند: لمس‌ها، کشیدن‌ها، ورود متن و واکنش رابط را بررسی می‌کنند. بر اساس تحقیق Android Developers, 2024، تست UI 70% از سناریوهای حساس کاربر را پوشش می‌دهد و امکان کشف عیوب چیدمان را که از بررسی‌های منطقی قابل دسترسی نیستند، فراهم می‌کند.

نکات کلیدی

  • تست UI — فرآیند بررسی رابط کاربری برنامه از طریق شبیه‌سازی اعمال کاربر: لمس‌ها، ورود متن و کشیدن‌ها.
  • Espresso — چارچوبی از Google برای تست UI برنامه‌های Android، همگام‌سازی با جریان UI و انتظار خودکار برای انیمیشن‌ها را فراهم می‌کند.
  • XCUITest — چارچوب داخلی Apple برای تست UI برنامه‌های iOS، یکپارچه شده در Xcode و کار از طریق برچسب‌های Accessibility.
  • Appium — ابزار چندسیستمی که اجازه نوشتن تست‌های UI به یک زبان برای Android و iOS با استفاده از پروتکل WebDriver را ممکن می‌سازد.
  • تست Snapshot تست‌های UI را با بررسی ظاهر صفحات تکمیل می‌کند — یک عکس از وضعیت مرجع را با رندر فعلی مقایسه می‌کند.

تست UI چیست؟

تست UI یک نوع بررسی خودکار است که در آن کد تست با رابط گرافیکی برنامه همان‌طور تعامل می‌کند که یک کاربر واقعی انجام می‌دهد. آزمایش عنصری را در صفحه — دکمه، فیلد متنی، لیست — پیدا می‌کند، روی آن عملی انجام می‌دهد و واکنش مورد انتظار رابط را بررسی می‌کند. به عنوان مثال، پس از ورود رمز عبور نامناسب، تست UI بررسی می‌کند که آیا پیام خطا با متن مناسب روی صفحه ظاهر شده است.

تفاوت اصلی تست‌های UI با سایر انواع خودکارسازی این است که آنها از طریق لایه Accessibility سیستم عامل کار می‌کنند، نه از طریق API داخلی برنامه. این به آن معنی است که تست‌های UI رابط را دقیقاً مانند کاربر و سیستم خواندن صفحه می‌بینند. به این ترتیب، تست‌های UI نه تنها فنکسیونالیت، بلکه دسترسی عناصر را نیز — مطابقت با نیازمندی‌های WCAG را بررسی می‌کنند.

بر اساس نظرسنجی JetBrains Developer Ecosystem 2023، 58% از تیم‌های موبایل از تست‌های UI در خط لوله CI/CD خود استفاده می‌کنند. میانگین پوشش تست‌های UI در پروژه‌های تجاری 30–40% صفحات برنامه است. پروژه‌هایی که از تست‌های UI استفاده می‌کنند، 25% کمتر نظرات منفی مربوط به کراش رابط در فروشگاه‌های برنامه دریافت می‌کنند.

تفاوت تست UI با تست واحد

تفاوت اصلی بین تست‌های UI و تست‌های واحد سطح چکیدگی است. تست‌های واحد با کلاس‌ها و توابع جداگانه‌ای کار می‌کنند که از چارچوب Android یا iOS جدا شده‌اند. آنها در JVM (برای Android) بدون راه‌اندازی شبیه‌ساز اجرا می‌شوند و میلی‌ثانیه طول می‌کشند. تست‌های UI روی دستگاه واقعی یا شبیه‌ساز اجرا می‌شوند، با سرویس‌های سیستم تعامل می‌کنند و برای یک سناریو به ثانیه یا دقیقه زمان نیاز دارند.

مخاطب هدف تست‌ها نیز متفاوت است. تست‌های UI سناریوهای سرتاسر کاربر را — ثبت نام، ثبت سفارش، جستجو را بررسی می‌کنند. تست‌های واحد منطق کسب و کار را پوشش می‌دهند: محاسبات، اعتبارسنجی، تبدیل داده‌ها. تست UI صحت محاسبه مالیات را بررسی نمی‌کند — آن بررسی می‌کند که مبلغ نهایی در صفحه نمایش داده می‌شود یا خیر. خود محاسبه توسط تست واحد بررسی می‌شود.

بر اساس Google Testing Blog (2020)، نسبت بهینه تست‌ها در پروژه باید از قاعده هرم تست پیروی کند: 70% تست واحد، 20% تست انتگرالیون و 10% تست UI. نقض این نسبت به نفع تست‌های UI منجر به افزایش زمان اجرا و شکندگی مجموعه تست می‌شود، زیرا تست‌های UI به تغییرات در چیدمان صفحات حساس هستند.

چارچوب‌های تست UI

برای Android چارچوب غالب Espresso است — کتابخانه‌ای از Google که در AndroidX Test ساخته شده است. Espresso به طور خودکار با جریان UI همگام می‌شود و قبل از انجام بررسی بعدی منتظر پایان انیمیشن‌ها و وظایف پس‌زمینه می‌ماند. برای Jetpack Compose از افزونه Compose UI Test استفاده می‌شود که به جای شناسه‌های نمایش سنتی از طریق گره‌های سمانتیک کار می‌کند.

برای iOS ابزار اصلی XCUITest است که در ترکیب Xcode قرار دارد. آزمایش‌ها به زبان Swift نوشته می‌شوند و از شناسه‌های Accessibility برای پیدا کردن عناصر استفاده می‌کنند. XCUITest از ضبط آزمایش‌ها از طریق قابلیت record و اتصال به سیستم‌های CI از طریق xcodebuild پشتیبانی می‌کند. برای پروژه‌های چندسیستمی، Appium بر پایه پروتکل WebDriver استفاده می‌شود که اجازه اجرای همین تست‌ها را در Android و iOS با تغییرات حداقل در کد فراهم می‌کند.

Espresso و Compose UI Test

Espresso با سیستم View سنتی از طریق onView و شناسه‌های منابع id کار می‌کند. Compose UI Test از لایه سمانتیک استفاده می‌کند که تست‌ها را از سلسله‌مراتب نمایش کمتر وابسته می‌کند. به عنوان مثال، جستجوی دکمه در Espresso: onView(withId(R.id.submit))، در Compose: onNodeWithTag(«submit»). تست‌های Compose به طور خودکار بازمونتاج را مدیریت می‌کنند و نیازی به انتظار صریح برای حالت بی‌کار ندارند.

XCUITest برای iOS

XCUITest از XCUIApplication به عنوان نقطه ورود استفاده می‌کند. هر عنصر رابط از طریق ویژگی‌های Accessibility جستجو می‌شود: accessibilityIdentifier برای دسترسی برنامه‌ای و accessibilityLabel برای VoiceOver. چارچوب از ضبط آزمایش‌ها از طریق قابلیت record در Xcode پشتیبانی می‌کند — توسعه‌دهنده اعمال را روی شبیه‌ساز انجام می‌دهد و Xcode کد آزمایش را تولید می‌کند. آزمایش‌های آماده از طریق xcodebuild test اجرا می‌شوند.

راه‌حل‌های چندسیستمی

Appium بر پایه پروتکل WebDriver است و از هر زبانی پشتیبانی می‌کند: Java، Python، JavaScript. برای جستجوی عناصر از راهبردهای id، xpath، class name و accessibility id استفاده می‌شود. Appium نیازمند نصب سرور و تنظیم Desired Capabilities — platformName، deviceName، appPackage است. یک جایگزین Maestro است که از سناریوهای YAML استفاده می‌کند و نیازی به کامپایل کد آزمایش ندارد.

  • Espresso — onView(withId(R.id.button)).perform(click()).check(matches(isDisplayed()))
  • XCUITest — app.buttons[«loginButton»].tap(); XCTAssertTrue(app.staticTexts[«welcome»].exists)
  • Appium — driver.findElement(By.id(«com.example:id/button»)).click()
  • Detox — چارچوبی از Wix برای React Native که با جریان JS همگام می‌شود
  • Maestro — ابزاری مدرن با سناریوهای YAML که نیازی به نوشتن کد ندارد

نمونه کدهای تست‌های UI

به تست‌های UI برای یک سناریو واحد — ورود به برنامه — در سه چارچوب مختلف نگاه می‌کنیم: Espresso برای Android، XCUITest برای iOS و Appium برای رویکرد چندسیستمی. سناریو: نام کاربری و رمز عبور را وارد کنید، دکمه ورود را فشار دهید، نمایش پیام خوش آمدگویی را بررسی کنید.

Android: Espresso

آزمایش در Espresso از onView برای پیدا کردن عنصر با شناسه و perform برای انجام عمل استفاده می‌کند. روش check با مطابق‌ساز isDisplayed تأیید می‌کند که عنصر در صفحه قابل مشاهده است.

kotlin
@RunWith(AndroidJUnit4::class)
class LoginUiTest {

    @Rule
    @JvmField
    val composeTestRule = createComposeRule()

    @Test
    fun login_withValidCredentials_showsWelcome() {
        composeTestRule
            .onNodeWithTag("emailField")
            .performTextInput("user@example.com")
        composeTestRule
            .onNodeWithTag("passwordField")
            .performTextInput("secret123")
        composeTestRule
            .onNodeWithTag("loginButton")
            .performClick()
        composeTestRule
            .onNodeWithText("خوش آمدید، کاربر!")
            .assertIsDisplayed()
    }
}

iOS: XCUITest

XCUITest از XCUIApplication برای دسترسی به عناصر رابط از طریق شناسه‌های Accessibility استفاده می‌کند. روش‌های tap() و exists() تعامل و بررسی را فراهم می‌کنند.

swift
class LoginUITests: XCTestCase {
    let app = XCUIApplication()

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

    func testLogin_withValidCredentials_showsWelcome() {
        app.textFields["emailField"].tap()
        app.textFields["emailField"].typeText("user@example.com")
        app.secureTextFields["passwordField"].tap()
        app.secureTextFields["passwordField"].typeText("رمز123")
        app.buttons["loginButton"].tap()
        XCTAssertTrue(app.staticTexts["Welcome, User!"].exists)
    }
}

بهترین روش‌های تست UI

اصل اول — به جای برچسب‌های متنی از شناسه‌های Accessibility برای پیدا کردن عناصر استفاده کنید. متن دکمه می‌تواند در لوکالی‌سازی تغییر کند، اما شناسه پایدار خواهد ماند. در Android این ویژگی contentDescription است، در iOS — accessibilityIdentifier. این رویکرد تست‌ها را از زبان رابط مستقل می‌کند و هزینه های پشتیبانی را در تغییر کپیرایتینگ کاهش می‌دهد.

از sleep() و تأخیرهای ثابت خودداری کنید — از مکانیسم‌های انتظار داخلی چارچوب استفاده کنید. Espresso به طور خودکار منتظر پایان انیمیشن‌ها و وظایف پس‌زمینه می‌ماند. XCUITest از XCTAssertTrue با timeout استفاده می‌کند. توقف‌های صریح تست‌ها را کند کرده و آنها را کمتر پایدار می‌کنند، خصوصاً در دستگاه‌های کند در محیط CI.

تست‌ها را بر اساس بهیتی گروه‌بندی کنید: تست‌های smoke (3–5 سناریو کلیدی) در هر commit اجرا می‌شوند، مجموعه کامل تست‌های UI — قبل از انتشار. بر اساس Google Testing Blog (2022)، تست‌های UI که بیش از 30 دقیقه در CI طول می‌کشند، دفعات اجرا را 40% کاهش می‌دهند که این امر افکاریت آنها را به عنوان ابزاری برای کشف زودهنگام رگرسیون کاهش می‌دهد.

محدودیت‌های تست‌های UI و راه‌های استتناب از آنها

تست‌های UI محدودیت‌هایی دارند. حساسیت به تغییرات چیدمان: تغییر شناسه، سلسله‌مراتب یا نوع عنصر تست را حتی با فنکسیونالیت ثابت می‌شکند. راه حل — استفاده از الگوی Page Object که انتخاب‌گرهای عناصر را در کلاس‌های جداگانه مرکزی می‌کند. در تغییر چیدمان، یک فایل Page Object اصلاح می‌شود، نه دهها تست.

زمان اجرا: اجرای بر روی دستگاه واقعی یا شبیه‌ساز 10–50 برابر بیشتر از تست واحد زمان می‌برد. راه حل — اجرای موازی تست‌های UI در چند دستگاه از طریق Firebase Test Lab یا AWS Device Farm. ناپایداری (flakiness) — مشکل رایج اجرای‌های CI ناشی از انیمیشن‌ها، تأخیرهای شبکه یا وضعیت شبیه‌ساز. برای مبارزه با flakiness، تکرار خودکار آزمایش‌های شکست خورده و تحلیل پایداری هر سناریو آزمایشی استفاده می‌شود.

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

چند تست UI برای یک صفحه لازم است؟

برای یک صفحه متوسط 3–5 تست UI کافی است: happy path، اعتبارسنجی خطا، وضعیت خالی، تغییر جهت‌گیری و بررسی Accessibility. صفحات پیچیده با وضعیت‌های متعدد — فرم‌های سفارش، تنظیمات — ممکن است برای پوشش کامل سناریوهای کلیدی به 10–15 تست نیاز داشته باشند.

آیا می‌توان از یک چارچوب برای Android و iOS استفاده کرد؟

بله، Appium و Maestro اجازه اجرای همین سناریوها را در هر دو پلتفرم می‌دهند. اما چارچوب‌های داخلی — Espresso و XCUITest — پایداری، سرعت و دسترسی بهتری به قابلیت‌های سطح پلتفرم را که از طریق پروکسی WebDriver در دسترس نیستند، فراهم می‌کنند.

چگونه UI را در Jetpack Compose آزمایش کنیم؟

برای Compose از کتابخانه Compose UI Test با مطابق‌سازهای سمانتیک استفاده می‌شود: onNodeWithText، onNodeWithTag، onNodeWithContentDescription. لایه سمانتیک Compose سلسله‌مراتب نمایش را چکیده می‌کند که تست‌ها را در مقایسه با Espresso سنتی برای سیستم View کمتر شکننده می‌کند.

آیا باید UI را روی دستگاه‌های فیزیکی آزمایش کرد؟

اجرای پایه تست‌های UI روی شبیه‌سازها در CI انجام می‌شود — سریع و ارزان است. تایید نهایی قبل از انتشار توصیه می‌شود روی دستگاه‌های فیزیکی از طریق Firebase Test Lab انجام شود تا ویژگی‌های سخت‌افزار واقعی را در نظر بگیرید: وضوح مختلف، نسخه‌های سیستم عامل و کارایی.

چگونه زمان اجرای تست‌های UI را کاهش دهیم؟

از اجرای موازی روی چند دستگاه استفاده کنید، انیمیشن‌ها را از طریق Developer Options روی شبیه‌ساز خاموش کنید، معماری پایه‌ای تست بسازید و مجموعه smoke را در هر commit و مجموعه کامل رگرسیون را بر اساس زمان‌بندی یا قبل از انتشار اجرا کنید.

خلاصه

  • تست UI رابط را از طریق شبیه‌سازی اعمال کاربر بررسی می‌کند — لمس‌ها، ورود متن، کشیدن‌ها.
  • Espresso و Compose UI Test — چارچوب‌های اصلی برای Android؛ XCUITest — برای iOS؛ Appium — برای پروژه‌های چندسیستمی.
  • هرم تست نسبت 70/20/10 را توصیه می‌کند: تست‌های واحد، انتگرالیون و UI به ترتیب.
  • شناسه‌های Accessibility تست‌های UI را در برابر لوکالی‌سازی و تغییرات چیدمان مقاوم می‌کنند.
  • Page Object انتخاب‌گرهای عناصر را مرکزی می‌کند و هزینه های پشتیبانی را در تغییر رابط کاهش می‌دهد.
  • تست‌های smoke (3–5 سناریو) در هر commit اجرا می‌شوند، مجموعه کامل — قبل از انتشار.
  • اجرای موازی روی شبیه‌سازها و خاموش‌کردن انیمیشن‌ها زمان اجرای تست‌های UI را در CI کاهش می‌دهند.

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

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

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

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