پایتون و اتوماسیون
درسهایی از اتوماسیون با Appium
با خوشبینی وارد Appium شدم. اتوماسیون تست موبایل قرار بود اطمینان بدهد، انتشارها را سریع کند و در رزومه عالی به نظر برسد. شش ماه بعد، تستهای لرزان داشتم، یک خط لوله CI که تصادفی شکست میخورد و تیمی که بیسروصدا اعتمادش به نتایج را از دست داده بود. Appium شرور نبود — رویکرد ما بود. اینها درسهایی هستند که اوضاع را برگرداندند.
درس ۱: Appium سلنیوم با پوست گوشی نیست
Appium از پروتکل WebDriver استفاده میکند که اگر سلنیوم بلد باشید آشنا به نظر میرسد. اما اپهای موبایل متفاوت رفتار میکنند: ژستها، وضعیت اپ، دیالوگهای سطح سیستمعامل و پردازههای پسزمینه همه دخالت میکنند. تستهایی که روی وب دسکتاپ کار میکنند روی موبایل مدام میشکنند، مگر اینکه از ابتدا برای موبایل طراحی کنید.
هر تست Appium در واقع دو تست است: یکی برای اپ شما و یکی برای سیستمعاملی که تصمیم میگیرد در بدترین لحظه یک دیالوگ مجوز نشان دهد.
درس ۲: سلکتورها همه چیزند
تستهای لرزان تقریباً همیشه به سلکتورهای بد برمیگردند. XPath راحت و شکننده است. شناسههای دسترسپذیری (accessibility id در iOS، content-desc در اندروید) را که تیم توسعه شما کنترل میکند ترجیح دهید:
# خوب: پایدار، معنایی
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "login-button")
# بد: با تغییر چیدمان میشکند
driver.find_element(AppiumBy.XPATH, "//android.widget.Button[3]")
با توسعهدهندگان کار کنید تا برچسبهای دسترسپذیری دوستدار تست را حین توسعه ویژگی اضافه کنند، نه بعد از آن.
درس ۳: انتظار، نه خواب
time.sleep(5) دشمن است. تست را وقتی سریع است کند و وقتی کند است لرزان میکند. از انتظارهای صریح برای شرایط استفاده کنید:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 15)
button = wait.until(
EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "submit"))
)
درس ۴: CI یک هیولای متفاوت است
تستهایی که محلی پاس میشوند در CI شکست میخورند چون شبیهسازها کندترند، صفحهها فرق دارند و اجراهای موازی برای منابع رقابت میکنند. درسها:
- برای مسیرهای حیاتی از مزارع دستگاه واقعی استفاده کنید؛ شبیهساز برای بقیه.
- بهجای هر حالت مرزی، تستهای کمتر و باکیفیتتر در CI اجرا کنید.
- به شبیهسازها timeout سخاوتمندانه بدهید و فقط روی شکستهای زیرساختی تلاش مجدد کنید، نه روی شکستهای ادعا.
درس ۵: مدل شیء صفحه عقلتان را نجات میدهد
هر صفحه را در کلاسی با متدهایی که نمایانگر اعمال کاربرند کپسوله کنید. وقتی رابط کاربری تغییر کند، یک فایل را بهروز میکنید، نه پنجاه تست را:
class LoginScreen:
def __init__(self, driver):
self.driver = driver
def login(self, email: str, password: str):
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "email").send_keys(email)
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "password").send_keys(password)
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "login-button").click()
درس ۶: بدانید کِی اتوماسیون نکنید
هر تست به Appium تعلق ندارد. صیقل بصری، زمانبندی انیمیشن و جریانهای اکتشافی یکباره دستی ارزانترند. مسیرهای حیاتی کاربر — ورود، تسویه، گردش کار اصلی — را اتومات کنید و تست دستی را برای بقیه بپذیرید.
| اتومات کنید | دستی تست کنید |
|---|---|
| ورود/ثبتنام | روانی انیمیشن |
| جریانهای اصلی کسبوکار | حالتهای مرزی رابط کاربری |
| پسرفت در انتشارها | کشف اکتشافی ویژگیهای جدید |
اشتباهات رایج
- تست فقط روی یک دستگاه. اندازه صفحه و نسخه سیستمعامل متفاوت رفتار میکنند.
- نبود مدیریت داده تست. تستهایی که به داده تولید یا حسابهای مشترک وابستهاند تصادم میکنند.
- نادیده گرفتن وضعیت اپ. بین تستها داده اپ را ریست کنید یا از نصب تازه استفاده کنید.
بهترین شیوهها
- روی کیفیت سلکتور از پیش سرمایهگذاری کنید — پربازدهترین اصلاح برای لرزش است.
- مجموعه تست را کوچک و سریع نگه دارید؛ تستهایی را که کسی به آنها اعتماد ندارد حذف کنید.
- شکستها را بهطور خودکار با اسکرینشات و source صفحه گزارش کنید.
- تستهای لرزان را هفتگی بازبینی کنید؛ قرنطینه یا رفع کنید، هرگز نادیده نگیرید.
جمعبندی
Appium قدرتمند است اما نسبت به میانبُرها بخشنده نیست. سلکتورهای پایدار، انتظارهای صریح، شیء صفحه، انتظارات واقعبینانه از CI و کنترل بیرحمانه دامنه، مجموعه ما را از یک بدهی به چیزی که واقعاً به آن اعتماد داریم تبدیل کرد. اتوماسیون موبایل برای مسیرهای حیاتی ارزش زحمتش را دارد — فقط سعی نکنید همه چیز را اتومات کنید. سه مسیر اصلی کاربرتان را انتخاب کنید و اول آن تستها را ضدگلوله کنید.