تست UI صحت نمایش و تعامل عناصر رابط کاربری برنامه موبایل — دکمهها، فیلدهای متنی، لیستها و جزء ناوبری را بررسی میکند. به عکس تستهای واحد که منطق کسب و کار را بررسی میکنند، تستهای UI اعمال کاربر را شبیهسازی میکنند: لمسها، کشیدنها، ورود متن و واکنش رابط را بررسی میکنند. بر اساس تحقیق Android Developers, 2024، تست UI 70% از سناریوهای حساس کاربر را پوشش میدهد و امکان کشف عیوب چیدمان را که از بررسیهای منطقی قابل دسترسی نیستند، فراهم میکند.
نکات کلیدی
تست UI یک نوع بررسی خودکار است که در آن کد تست با رابط گرافیکی برنامه همانطور تعامل میکند که یک کاربر واقعی انجام میدهد. آزمایش عنصری را در صفحه — دکمه، فیلد متنی، لیست — پیدا میکند، روی آن عملی انجام میدهد و واکنش مورد انتظار رابط را بررسی میکند. به عنوان مثال، پس از ورود رمز عبور نامناسب، تست UI بررسی میکند که آیا پیام خطا با متن مناسب روی صفحه ظاهر شده است.
تفاوت اصلی تستهای UI با سایر انواع خودکارسازی این است که آنها از طریق لایه Accessibility سیستم عامل کار میکنند، نه از طریق API داخلی برنامه. این به آن معنی است که تستهای UI رابط را دقیقاً مانند کاربر و سیستم خواندن صفحه میبینند. به این ترتیب، تستهای UI نه تنها فنکسیونالیت، بلکه دسترسی عناصر را نیز — مطابقت با نیازمندیهای WCAG را بررسی میکنند.
بر اساس نظرسنجی JetBrains Developer Ecosystem 2023، 58% از تیمهای موبایل از تستهای UI در خط لوله CI/CD خود استفاده میکنند. میانگین پوشش تستهای UI در پروژههای تجاری 30–40% صفحات برنامه است. پروژههایی که از تستهای UI استفاده میکنند، 25% کمتر نظرات منفی مربوط به کراش رابط در فروشگاههای برنامه دریافت میکنند.
تفاوت اصلی بین تستهای UI و تستهای واحد سطح چکیدگی است. تستهای واحد با کلاسها و توابع جداگانهای کار میکنند که از چارچوب Android یا iOS جدا شدهاند. آنها در JVM (برای Android) بدون راهاندازی شبیهساز اجرا میشوند و میلیثانیه طول میکشند. تستهای UI روی دستگاه واقعی یا شبیهساز اجرا میشوند، با سرویسهای سیستم تعامل میکنند و برای یک سناریو به ثانیه یا دقیقه زمان نیاز دارند.
مخاطب هدف تستها نیز متفاوت است. تستهای UI سناریوهای سرتاسر کاربر را — ثبت نام، ثبت سفارش، جستجو را بررسی میکنند. تستهای واحد منطق کسب و کار را پوشش میدهند: محاسبات، اعتبارسنجی، تبدیل دادهها. تست UI صحت محاسبه مالیات را بررسی نمیکند — آن بررسی میکند که مبلغ نهایی در صفحه نمایش داده میشود یا خیر. خود محاسبه توسط تست واحد بررسی میشود.
بر اساس Google Testing Blog (2020)، نسبت بهینه تستها در پروژه باید از قاعده هرم تست پیروی کند: 70% تست واحد، 20% تست انتگرالیون و 10% تست 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 با سیستم View سنتی از طریق onView و شناسههای منابع id کار میکند. Compose UI Test از لایه سمانتیک استفاده میکند که تستها را از سلسلهمراتب نمایش کمتر وابسته میکند. به عنوان مثال، جستجوی دکمه در Espresso: onView(withId(R.id.submit))، در Compose: onNodeWithTag(«submit»). تستهای Compose به طور خودکار بازمونتاج را مدیریت میکنند و نیازی به انتظار صریح برای حالت بیکار ندارند.
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 استفاده میکند و نیازی به کامپایل کد آزمایش ندارد.
به تستهای UI برای یک سناریو واحد — ورود به برنامه — در سه چارچوب مختلف نگاه میکنیم: Espresso برای Android، XCUITest برای iOS و Appium برای رویکرد چندسیستمی. سناریو: نام کاربری و رمز عبور را وارد کنید، دکمه ورود را فشار دهید، نمایش پیام خوش آمدگویی را بررسی کنید.
آزمایش در Espresso از onView برای پیدا کردن عنصر با شناسه و perform برای انجام عمل استفاده میکند. روش check با مطابقساز isDisplayed تأیید میکند که عنصر در صفحه قابل مشاهده است.
@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()
}
}
XCUITest از XCUIApplication برای دسترسی به عناصر رابط از طریق شناسههای Accessibility استفاده میکند. روشهای tap() و exists() تعامل و بررسی را فراهم میکنند.
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)
}
}
اصل اول — به جای برچسبهای متنی از شناسههای 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 محدودیتهایی دارند. حساسیت به تغییرات چیدمان: تغییر شناسه، سلسلهمراتب یا نوع عنصر تست را حتی با فنکسیونالیت ثابت میشکند. راه حل — استفاده از الگوی Page Object که انتخابگرهای عناصر را در کلاسهای جداگانه مرکزی میکند. در تغییر چیدمان، یک فایل Page Object اصلاح میشود، نه دهها تست.
زمان اجرا: اجرای بر روی دستگاه واقعی یا شبیهساز 10–50 برابر بیشتر از تست واحد زمان میبرد. راه حل — اجرای موازی تستهای UI در چند دستگاه از طریق Firebase Test Lab یا AWS Device Farm. ناپایداری (flakiness) — مشکل رایج اجرایهای CI ناشی از انیمیشنها، تأخیرهای شبکه یا وضعیت شبیهساز. برای مبارزه با flakiness، تکرار خودکار آزمایشهای شکست خورده و تحلیل پایداری هر سناریو آزمایشی استفاده میشود.
سوالات متداول
برای یک صفحه متوسط 3–5 تست UI کافی است: happy path، اعتبارسنجی خطا، وضعیت خالی، تغییر جهتگیری و بررسی Accessibility. صفحات پیچیده با وضعیتهای متعدد — فرمهای سفارش، تنظیمات — ممکن است برای پوشش کامل سناریوهای کلیدی به 10–15 تست نیاز داشته باشند.
بله، Appium و Maestro اجازه اجرای همین سناریوها را در هر دو پلتفرم میدهند. اما چارچوبهای داخلی — Espresso و XCUITest — پایداری، سرعت و دسترسی بهتری به قابلیتهای سطح پلتفرم را که از طریق پروکسی WebDriver در دسترس نیستند، فراهم میکنند.
برای Compose از کتابخانه Compose UI Test با مطابقسازهای سمانتیک استفاده میشود: onNodeWithText، onNodeWithTag، onNodeWithContentDescription. لایه سمانتیک Compose سلسلهمراتب نمایش را چکیده میکند که تستها را در مقایسه با Espresso سنتی برای سیستم View کمتر شکننده میکند.
اجرای پایه تستهای UI روی شبیهسازها در CI انجام میشود — سریع و ارزان است. تایید نهایی قبل از انتشار توصیه میشود روی دستگاههای فیزیکی از طریق Firebase Test Lab انجام شود تا ویژگیهای سختافزار واقعی را در نظر بگیرید: وضوح مختلف، نسخههای سیستم عامل و کارایی.
از اجرای موازی روی چند دستگاه استفاده کنید، انیمیشنها را از طریق Developer Options روی شبیهساز خاموش کنید، معماری پایهای تست بسازید و مجموعه smoke را در هر commit و مجموعه کامل رگرسیون را بر اساس زمانبندی یا قبل از انتشار اجرا کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید