تفاوت تست وب و موبایل را نمیتوان با «مرورگر در برابر گوشی» یا «ماوس در برابر لمس» توضیح داد. یک PWA روی گوشی میتواند نصب شود، آفلاین کار کند، اعلان بگیرد و در پسزمینه رویداد پردازش کند؛ یک اپلیکیشن Hybrid ممکن است همزمان به WebView، Plugin نیتیو و API سرور وابسته باشد؛ و یک وباپ دسکتاپ نیز ممکن است زیر فشار حافظه، شبکهٔ ناپایدار، صفحهخوان و ورودی لمسی اجرا شود. واحد درست مقایسه، برچسب Web/Mobile نیست؛ سطح محصول، Artifact، Runtime، مسیر توزیع، پلتفرم و زمینهٔ استفاده است.
این راهنما یک Client Platform Test Matrix قابلممیزی میسازد: ابتدا چیزی را که واقعاً تحویل میشود هویتگذاری میکنیم، سپس Browser/OS/Device/WebView، نصب و Update، ورودی و دسترسپذیری، Permission و Sensor، Lifecycle و State، شبکه، منابع، امنیت، اتوماسیون و Fidelity شواهد را کنار هم میگذاریم. خروجی، فهرست بیپایان دستگاهها نیست؛ یک تصمیم پوشش محدود، ریسکمحور و قابلاصلاح است.
پاسخ کوتاه: تفاوت تست وب و موبایل چیست؟
تست وب معمولاً Runtime مرورگر، مدل Origin و Cache، تفاوت Engineها، Responsive layout، Keyboard/Pointer/Touch، Tab lifecycle و شیوهٔ استقرار سمت سرور را برجسته میکند. تست اپ نصبشده معمولاً Package و Signing، نصب/ارتقا/Migration، چرخهٔ Foreground/Background/Termination، Permission، قابلیتهای دستگاه، Store و منابع سختافزاری را برجسته میکند. اما این مرز نفوذناپذیر نیست: Mobile Web بخشی از ریسکهای دستگاه را دارد و PWA بخشی از رفتار نصب، Storage، Offline و Background را؛ Hybrid نیز چند Runtime را یکجا حمل میکند.
| پرسش | وب Responsive/PWA | Native/Hybrid نصبشده | قاعدهٔ تصمیم |
|---|---|---|---|
| چه چیزی اجرا میشود؟ | URL، Asset، Service Worker و داده در Browser | Package/Bundle، کد نیتیو یا WebView و دادهٔ محلی | Artifact و Runtime دقیق را ثبت کنید |
| چگونه تغییر میکند؟ | Deploy سرور، Cache و گاهی Update برنامهٔ نصبشده | Store/Enterprise/Sideload، Signing و Migration | مسیر نصب و Update را جدا بیازمایید |
| چه چیزی آن را متوقف میکند؟ | بستن/Discard تب، Browser policy، Service Worker lifecycle | Background، Process death، OS policy، Force stop | State و Recovery را صریح تعریف کنید |
| به چه قابلیتهایی دسترسی دارد؟ | APIهای مرورگر با Permission و محدودیت پشتیبانی | APIهای پلتفرم، Permission، Entitlement و Plugin | Capability را بهازای Runtime اندازه بگیرید |
| چه شواهدی معتبر است؟ | Browser automation، DevTools و دستگاه واقعی | Host/Emulator/Simulator/Device و Platform tools | Fidelity هر ادعا را جدا ثبت کنید |
بنابراین گزارهٔ «موبایل همیشه پیچیدهتر و گرانتر است» معتبر نیست. یک اپ Native تکپلتفرمی با دامنهٔ محدود ممکن است از وبی که چهار Engine، چند ورودی، Offline، افزونههای سازمانی و دهها Breakpoint دارد کوچکتر باشد. هزینه تابع تعداد ترکیبهای پشتیبانیشده × عمق ریسک × Fidelity لازم × نرخ تغییر است، نه نام کانال.
مرز این مقاله با راهنمای تست موبایل
اگر به سناریوهای اجرایی Android/iOS، Permission، Deep link، Notification، Process death و Release checklist نیاز دارید، راهنمای تست اپلیکیشن موبایل مرجع تخصصی آن است. این صفحه مالک پرسش دیگری است: وقتی محصول روی چند سطح Web، PWA، Native یا Hybrid عرضه میشود، چگونه تفاوتها را به یک ماتریس مشترک و قابلدفاع تبدیل کنیم و کجا آزمون مشترک یا اختصاصی بسازیم؟
پیش از تست، Surface را هویتگذاری کنید
نام بازاری «اپ ما» برای Test Object کافی نیست. یک محصول ممکن است وب عمومی، پنل Responsive، PWA نصبشده، اپ Android، اپ iOS و یک Wrapper دسکتاپ داشته باشد؛ حتی دو نسخهٔ Hybrid ممکن است WebView یا Pluginهای متفاوتی حمل کنند. برای هر Surface یک رکورد نسخهدار بسازید:
ClientSurfaceRecord SurfaceID: CS-ANDROID-CONSUMER ArtifactFamily: native | hybrid | pwa | responsive-web | mobile-web | wrapper Artifact: package/bundle/URL + version + digest Build: commit + pipeline + configuration + signing channel Runtime: OS + browser/engine/WebView/app framework Distribution: web deploy | store | enterprise | sideload SupportPolicy: versions/devices/browsers/locales + effective date CriticalJourneys: IDs, not prose Capabilities: camera/location/notification/storage/biometric/... DataAndDependencies: API/cache/SDK/provider Owner / reviewer / facts-as-of / expiry
این رکورد مانع چند خطای رایج میشود: نتیجهٔ Debug به Release تعمیم داده نمیشود؛ تست Chrome دسکتاپ به WebView همان نسخه نسبت داده نمیشود؛ و «Hybrid» بهاشتباه به معنای یک معماری ثابت گرفته نمیشود. معماری و Pluginهای واقعی باید از Manifest، Dependency lock و Build evidence خوانده شوند.
شش خانوادهٔ Surface و ریسک غالب هرکدام
| خانواده | Runtime غالب | ریسک برجسته | چیزی که نباید فرض شود |
|---|---|---|---|
| Responsive Web | Browser در Desktop/Mobile | Engine، Viewport، Input، Cache و Deploy | فقط Desktop و شبکهٔ پایدار |
| Mobile Web | Browser موبایل | Viewport پویا، Keyboard، Touch، Memory و Network | همان Desktop با صفحهٔ کوچک |
| PWA | Browser + Service Worker + نصب اختیاری | Cache/version، Offline، Update و قابلیتهای ناهمگون | رفتار برابر با Native |
| Native | OS SDK و باینری پلتفرم | Lifecycle، Permission، Signing، Resource و Store | رفتار یکسان Android و iOS |
| Hybrid | Container + WebView + Plugin/API | سه مرز Web/Bridge/Native و نسخهٔ WebView | یک Technology یا Fidelity ثابت |
| Desktop wrapper | Container/Engine + OS دسکتاپ | Update، Window، File system و OS integration | معادل Browser معمولی |
این طبقهبندی برای شروع است، نه برچسب حقیقت. اگر یک قابلیت Native داخل یک صفحهٔ Web embed شده، آن قابلیت دو Runtime و یک Bridge دارد. Surface را تا جایی خرد کنید که Risk، Owner، Build و Oracle معنیدار شوند؛ نه تا حدی که ماتریس غیرقابلنگهداری شود.
Runtime: Browser، Engine و WebView را یکی نگیرید
نام مرورگر تنها عامل نیست. Engine، نسخه، OS، Feature flag، Extension/Policy سازمانی، Cookie/Storage policy و WebView تعبیهشده میتوانند رفتار را تغییر دهند. WebView ممکن است مستقل از اپ یا همراه پلتفرم Update شود؛ بنابراین «روی Android ۱۵ تست شد» بدون نسخهٔ WebView شواهد ناقص است. در وب نیز یک Browser روی Desktop و همان نام روی Mobile الزاماً مجموعهٔ قابلیت و رفتار یکسانی ندارد.
- DOM/CSS/JavaScript feature و fallback؛
- Cookie، SameSite، Storage quota و eviction؛
- Back/Forward cache، refresh و history؛
- Download/upload، file picker و camera capture؛
- Viewport، safe area، zoom و virtual keyboard؛
- Tab discard، sleep، restore و private mode؛
- WebView bridge، navigation allowlist و external link؛
- Browser/OS update مستقل و Regression پس از Update.
برای طراحی جزئی Browser/Device/OS و کاهش Cross-product، راهنمای تست سازگاری و Compatibility Matrix را بهعنوان سند پاییندستی استفاده کنید؛ این مقاله فقط ورودی Surface و تفاوت پلتفرم را به آن میدهد.
توزیع، نصب، Update و Rollback
در Web deploy سمت سرور میتواند همهٔ کاربران را سریع به نسخهٔ تازه ببرد، اما CDN، Service Worker و Cache ممکن است Assetهای قدیم و جدید را مخلوط کنند. در اپ نصبشده، Rollout مرحلهای، Review فروشگاه، Signing، نسخهٔ OS و رفتار کاربر در Update باعث همزیستی چند نسخه میشود. هیچکدام ذاتاً ساده نیستند؛ Failure mode متفاوت است.
| رویداد | وب/PWA | اپ نصبشده | Oracle نمونه |
|---|---|---|---|
| نسخهٔ تازه | Cache invalidation و Asset سازگار | Package/Bundle و Migration | نسخهٔ Client/Schema/API قابلشناسایی است |
| کاربر قدیمی | تب باز یا Service Worker قدیمی | Binary قدیمی در Rollout | Backend پنجرهٔ سازگاری را رعایت میکند |
| قطع Update | دانلود ناقص Asset/Cache | کمبود Storage یا نصب ناموفق | نسخهٔ قابلاجرا و State سالم باقی میماند |
| Rollback | Deploy قبلی و Cache strategy | اغلب Roll-forward یا محدودیت Store | داده با نسخهٔ برگشتی ناسازگار نمیشود |
| حذف | پاککردن Site data/PWA | Uninstall و دادهٔ Server/Backup | سیاست retention و session روشن است |
Device Matrix را از جمعیت پشتیبانیشده بسازید
«محبوبترین گوشیهای بازار» بهتنهایی ورودی خوبی نیست. ماتریس باید از Support policy، دادهٔ استفادهٔ حداقلی و مجاز، Crash/Support، قرارداد، ریسک جریان و تغییرات آینده ساخته شود. دادهٔ Analytics هم حقیقت کامل نیست: کاربرانی که بهسبب ناسازگاری هرگز وارد محصول نشدهاند در Telemetry دیده نمیشوند.
- Tier 0: ترکیب مرجع توسعه برای بازخورد سریع؛
- Tier 1: ترکیبهای پرترافیک یا پرپیامد برای هر Release؛
- Tier 2: مرزهای پشتیبانی، کممنبع، نسخهٔ قدیمی و اندازهٔ خاص؛
- Tier 3: نمونهبرداری چرخشی و ترکیبهای کموقوع؛
- Seed اجباری: ترکیبهای کمتکرار اما پرخطر، مستقل از Pairwise؛
- Unsupported: صریح، قابلارتباط و دارای رفتار graceful در صورت امکان.
برای عوامل متعدد از Partition و سپس Pairwise با Constraint استفاده کنید، ولی Pairwise اثبات Coverage بازار یا کشف همهٔ برهمکنشها نیست. پرداخت روی دستگاه کمحافظه با شبکهٔ ضعیف، یا صفحهخوان با Keyboard و RTL، ممکن است Seed سهعاملی اجباری باشد.
دستگاه واقعی، Emulator، Simulator و Device Farm
انتخاب ابزار باید به Claim وصل شود. مستندات رسمی Android، لایههای تست را با Scope، Fidelity، محل اجرا و زمان اجرا تفکیک میکند و آن را خط مبنا میداند، نه نسخهٔ اجباری برای همهٔ تیمها. مستندات Apple نیز Simulator را برای بازخورد سریع مناسب میداند، اما تصریح میکند پیش از انتشار، رفتار و معیارها روی دستگاه فیزیکی سنجیده شوند؛ Simulator کارایی واقعی دستگاه هدف را شبیهسازی نمیکند. این دو منبع مجوز «همهچیز روی Device» یا «Emulator کافی است» نیستند: راهبرد رسمی تست Android و راهنمای Build و اجرای Apple.
| محیط | ادعای مناسب | ادعای نامعتبر بدون شاهد دیگر |
|---|---|---|
| Host/Unit | منطق، تبدیل و State reducer | Integration واقعی پلتفرم |
| Emulator/Simulator | پوشش سریع OS/Viewport و Flow کنترلشده | Battery، thermal، حس لمس و کارایی واقعی |
| دستگاه واقعی داخلی | Hardware، resource، gesture و platform behavior | نمایندگی کل بازار |
| Device farm | تنوع مدل/OS و Regression توزیعشده | شبکه و زمینهٔ کاربر ایران یا نبود bias |
| Beta محدود | رفتار در زمینهٔ کنترلشدهٔ واقعیتر | کیفیت عمومی یا نبود defect |
| Production telemetry | سیگنال جمعیت و خطای مشاهدهشده | علت قطعی یا تجربهٔ کاربران غایب |
ورودی فقط Mouse در وب و Gesture در موبایل نیست
یک وباپ روی لپتاپ لمسی ممکن است Touch، Mouse، Keyboard و Stylus را همزمان ببیند؛ یک اپ موبایل با Keyboard خارجی، Switch control، Voice control یا Screen reader کار میکند. Hover نباید تنها راه آشکارشدن عمل باشد و Gesture پیچیده باید جایگزین قابلدسترس داشته باشد. Matrix ورودی را مستقل از نام Surface ثبت کنید.
- Tap/click، double action و long press؛
- Swipe، drag، pinch، rotate و cancellation؛
- Keyboard order، shortcut، Enter/Space/Escape و focus visibility؛
- Pointer coarse/fine، hover none/available و چند ورودی همزمان؛
- Virtual keyboard، autofill، composition و تغییر viewport؛
- Screen reader، Voice/Switch و semantics؛
- اندازهٔ هدف، فاصله، one-handed reach و accidental activation؛
- orientation، resize، multi-window و fold posture.
دسترسپذیری مرز Web/Native را قطع نمیکند
وب و اپ نیتیو هر دو به ساختار معنایی، نام/نقش/وضعیت، ترتیب Focus، کنتراست، Resize، جایگزین حرکت و آزمون با فناوری کمکی نیاز دارند؛ ابزار و Accessibility tree متفاوت است. W3C توضیح میدهد که دسترسپذیری موبایل موضوع جدا از دسترسپذیری وب نیست و راهنمای WAI برای موبایل استانداردها و کاربرد آنها را در Mobile Web و App کنار هم قرار میدهد. برای معیارها، روشها و محدودیت ارزیابی، به راهنمای تست دسترسپذیری و WCAG ۲.۲ رجوع کنید.
عبور Axe/Lighthouse یا Accessibility Scanner فقط یافتههای قابلخودکارسازی را پوشش میدهد. Screen reader test یک کارشناس نیز نمایندهٔ همهٔ کاربران نیست. Conformance claim به Scope، نسخه، معیار، روش و یافتههای باز نیاز دارد؛ ارزیابی کاربر با معلولیت مکمل است و جای Conformance check را نمیگیرد.
قابلیت، Permission و Sensor را Capability-based کنید
مرورگرها هم میتوانند با اجازه به Location، Camera، Microphone، Notification، Clipboard، File، Credential و برخی قابلیتهای دیگر دسترسی دهند؛ اپ نصبشده هم ممکن است Permission یا سختافزار لازم را نداشته باشد. بهجای «وب ندارد/موبایل دارد»، برای هر قابلیت این زنجیره را بنویسید:
CapabilityContract Capability → supported surface/runtime/version Trigger → user explanation → permission state Allow / deny / deny-permanently / revoke / restricted Approximate / precise / foreground / background scope Hardware absent / busy / low-quality / interrupted Data produced → destination → retention → deletion Fallback → recovery → observable evidence → claim limit
Grant شدن Permission موفقیت قابلیت را ثابت نمیکند. Camera ممکن است توسط برنامهای دیگر مشغول باشد؛ Location میتواند تقریبی یا قدیمی باشد؛ Notification ممکن است در سطح OS یا Channel خاموش شود؛ Biometric میتواند Enrollment تغییر کند. Oracle باید خروجی محصول و رفتار fallback را بسنجد.
Lifecycle، Background و بازیابی State
اپ نصبشده رویدادهای صریح Foreground/Background/Termination دارد، اما وب نیز Lifecycle دارد: تب مخفی میشود، Browser آن را Discard میکند، صفحه به Back/Forward cache میرود، Service Worker متوقف و بعداً بیدار میشود، یا PWA بسته میشود. MDN نشان میدهد Service Worker میتواند Offline و بعضی عملیات پسزمینه را ممکن کند، اما دائماً زنده نمیماند و Browser میتواند آن را متوقف کند؛ پس راهنمای رسمی MDN دربارهٔ Offline و Background مجوز فرض «اجرای همیشگی» نیست.
| Transition | State مورد انتظار | آزمون خرابی | Evidence |
|---|---|---|---|
| Active → hidden/background | ذخیره یا پاکسازی طبق سیاست | وسط عملیات حساس | UI + local/server state |
| Background → terminated/discarded | بدون اتکا به callback قطعی | فشار حافظه/بستن فرایند | restart trace |
| Cold start/restore | State معتبر، نه snapshot کهنه | نسخه و schema تازه | build/state IDs |
| External round-trip | بازگشت idempotent | Browser/PSP/Camera دیرهنگام | attempt + server ledger |
| Update while inactive | Migration قابلبازیابی | Asset/DB نسخهٔ مخلوط | migration log بدون دادهٔ حساس |
Offline، Cache، Storage و همگامسازی
Offline فقط نمایش پیام «اینترنت قطع است» نیست. ابتدا Product contract را تعیین کنید: چه چیزی Read-only از Cache باز میشود؟ کدام Command صف میشود؟ ترتیب، انقضا، تعارض، تکرار و لغو چگونه مدیریت میشوند؟ Cache مرورگر، IndexedDB، Secure storage، فایل یا Database محلی Failure mode متفاوت دارند، اما مسئلهٔ اصلی مشترک است: State محلی و سرور چگونه دوباره همگرا میشوند؟
SyncScenario OperationID: SYN-ORDER-017 (fictional) StartState: client-v12 / server-v44 Transition: offline → enqueue → reconnect → duplicate callback Ordering: client sequence + server idempotency key ConflictPolicy: server-authoritative fields + explicit user choice Expiry/Cancel: bounded and visible Oracle: one accepted order, one final payment attempt, no silent loss Evidence: client events + stub ledger + timestamps + limitations
تست UI تنها نباید محل اثبات Server idempotency یا Authorization باشد. قرارداد Backend را با راهنمای تست API و Integrationهای Client/SDK/Service را در سطح مناسب جدا کنید، سپس چند سفر End-to-End محدود برای اتصال شواهد نگه دارید.
شبکه برای هر دو سطح متغیر است
فرض «وب روی Ethernet پایدار است» یک خطای نمونهگیری است. کاربر ممکن است وب را روی موبایل، Hotspot، VPN، Proxy سازمانی یا شبکهٔ پرتاخیر ایران باز کند. اپ موبایل هم الزاماً در حال حرکت نیست. ماتریس شبکه را از Journey و Dependency بسازید:
- Offline در شروع، وسط Read و وسط Command؛
- Latency و jitter، bandwidth محدود و packet loss کنترلشده؛
- تغییر interface یا IP و قطع کوتاه؛
- DNS/TLS/Proxy/Captive portal با دادهٔ آزمایشی مجاز؛
- Timeout پیش از commit و پس از commit؛
- پاسخ دیرهنگام، تکراری، ناقص یا خارج از ترتیب؛
- Retry-After، backoff، cancel و app/page close؛
- Backend/SDK/CDN/Push/Map/Analytics در دسترس یا مسدود؛
- مسیر جایگزین و رفتار degraded برای دسترسی ناپایدار از ایران.
شبیهسازی Network در DevTools یا Emulator کنترلپذیر است، اما نمایندهٔ همهٔ ویژگیهای رادیو، Carrier، VPN یا مسیر بینالمللی نیست. نتیجه باید Profile، ابزار، زمان، مسیر و محدودیت را ثبت کند.
Performance را Client، Server و End-to-End جدا کنید
زمان پاسخ مشاهدهشده ترکیبی از Client work، شبکه، Queue و Backend است. FPS یا startup روی Simulator، Battery روی لپتاپ و Load server از UI موبایل، هر سه Oracle نامناسباند. برنامهٔ تست عملکرد باید مدل بار و معیار پذیرش Backend را جدا نگه دارد؛ Matrix کلاینت این شاخصها را با Build و دستگاه هدف پیوند میدهد:
| سطح | نمونهٔ معیار | شرط اندازهگیری | محدودیت |
|---|---|---|---|
| Client startup | cold/warm time | Release build، device tier، sample count | با server latency مخلوط نشود |
| Rendering | frame time/jank | screen/data/gesture ثابت | میانگین بهتنهایی کافی نیست |
| Memory/CPU | peak/growth/sustained use | OS/device/thermal state | Debug profiler overhead |
| Energy/data | مصرف در سناریوی زماندار | سختافزار واقعی و baseline | به همهٔ دستگاهها تعمیم ندارد |
| Web vitals | metric و percentile تعریفشده | Browser/population/window | Lab و field دو شاهد متفاوتاند |
| End-to-end | user-visible completion | client/network/server trace | علت را بدون تفکیک ثابت نمیکند |
Threshold باید از هدف محصول، Baseline، کاربر و Risk بیاید. یک عدد جهانی مانند «همهٔ صفحات زیر دو ثانیه» یا «مصرف CPU کمتر از ده درصد» بدون workload، device و percentile قابلممیزی نیست.
زبان فارسی، RTL و زمینهٔ ایران
Locale یک ردیف تزئینی در Matrix نیست. Browser، WebView، فونت سیستم، Keyboard، Calendar و Formatter پلتفرم میتوانند نتیجهٔ متفاوتی بسازند. سناریوی ایران باید بدون ادعای حقوقی یا مالی، حداقل این مرزها را ثبت کند:
- UTF-۸، جهت پایه و Bidi میان متن فارسی و شناسهٔ LTR؛
- ی/ی و ک/ک، نیمفاصله و شکلهای Unicode؛
- رقم فارسی، عربی و لاتین در input، paste، display و search؛
- IRR بهعنوان مقدار canonical و «تومان» فقط با برچسب و تبدیل صریح؛
- زمان UTC برای رویداد و Asia/Tehran برای نمایش؛
- تاریخ جلالی فقط presentation مگر قرارداد خلاف آن بگوید؛
- طول متن، line break، truncation و Font scale؛
- دسترسپذیری نام/نقش/مقدار در RTL؛
- شبکه، CDN، SDK و مسیر جایگزینِ از پیش آزمودهشده از ایران.
برای Caseهای دقیقتر Unicode، تاریخ، مبلغ، جستوجو و ترجمه، چکلیست تست i18n، l10n، فارسی و RTL را به Surfaceهای همین ماتریس اعمال کنید.
امنیت و حریم خصوصی: مدل تهدید بر اساس Surface
وب و اپ نصبشده مرز اعتماد متفاوت دارند، ولی هیچکدام «امن» یا «ناامن» ذاتی نیست. Browser روی Origin، Cookie، CSP و Web platform تکیه میکند؛ اپ نصبشده Package، IPC/URL scheme، local storage، backup، clipboard، screenshot، certificate handling و SDK دارد؛ Hybrid علاوه بر اینها Bridge و WebView navigation را حمل میکند.
| سطح حمله/حریم خصوصی | وب/PWA | Native/Hybrid |
|---|---|---|
| ورودی ناامن | URL/DOM/message/file/deep link | Intent/URL scheme/IPC/file/notification |
| State محلی | cookie/cache/storage/service worker | database/file/preferences/key store/backup |
| مرز کد | origin/third-party script/extension | SDK/plugin/WebView bridge/package |
| نشت نمایشی | history/autofill/screenshot/shared browser | notification/app switcher/clipboard/screenshot |
| Update | supply chain/deploy/cache | signing/store/library/package |
| کنترل واقعی | Authorization و integrity حساس باید سمت مورد اعتماد enforce شود؛ پنهانکردن UI کنترل نیست | |
ثبت Network log، Video و Crash dump میتواند Token، پیام، مکان یا شناسهٔ شخصی را افشا کند. Evidence contract باید minimization، redaction، دسترسی، retention و deletion داشته باشد. عبور Scanner یا Pinning یک کنترل، اثبات امنیت/حریم خصوصی محصول نیست.
اتوماسیون مشترک و اختصاصی را چگونه تقسیم کنیم؟
یک زبان برنامهنویسی یا Vendor مشترک، مدل تست یکسان ایجاد نمیکند. WebDriver، Browser automation، native UI framework، API checks و component tests سطح، synchronization و locator متفاوت دارند. «Appium برای هر دو» یا «یک suite برای همه» بهتنهایی Strategy نیست. برای انتخاب کاندیدا، هزینه و محدودیت، راهنمای اتوماسیون تست را مبنا قرار دهید.
- قواعد Domain و State transition را در لایهٔ مشترک سریع نگه دارید؛
- Contract/API را مستقل از UI هر Surface بسنجید؛
- Component و screenshot را با Runtime مربوط اجرا کنید؛
- تعداد کمی Critical journey را در هر Surface واقعی نگه دارید؛
- Permission، lifecycle، sensor و install را اختصاصی پلتفرم کنید؛
- Selector و Test hook را بدون تغییر semantics محصول طراحی کنید؛
- Retry همهٔ Attemptها را حفظ کند و flaky را سبز پنهان نکند؛
- هر Check یک Claim و Claim limit داشته باشد؛
- Suite براساس Support matrix و change impact انتخاب شود؛
- هزینهٔ device farm، queue، data و triage در TCO بیاید.
Automation Coverage Map
| ریسک | لایهٔ ارزان نخست | شاهد کلاینت | شاهد Fidelity بالا |
|---|---|---|---|
| قانون مبلغ | Unit/property | component formatting | یک journey محدود |
| API schema/idempotency | contract/API | client error mapping | fault-injected journey |
| layout/RTL | component/screenshot | browser/device matrix | manual AT/visual sampling |
| permission | state logic | emulator/simulator | physical device + revoke |
| performance | microbenchmark | lab profile | release/device/field evidence |
| install/update | migration tests | packaged artifact | real distribution path |
تعداد Check، درصد سبزی یا یک Run روی Device Farm نشاندهندهٔ Coverage جمعیت نیست. برای هر ردیف بگویید چه سؤال و کدام Risk پوشش داده شده، روی چه Artifact/Build/Runtime، با چه Oracle و تا چه تاریخی.
Evidence Contract؛ نتیجه به چه ادعایی پاسخ میدهد؟
ClientEvidenceRecord EvidenceID / test-question / risk SurfaceID / artifact digest / build / configuration Runtime: OS + browser/engine/WebView + device profile Distribution/install/update state Input/accessibility/locale/network/resource profile Data/dependency/stub versions Oracle source + rule + tolerance + observation point Attempt/result: PASS | FAIL | ERROR | SKIPPED | INCONCLUSIVE Raw evidence digest + time + collector + redaction Known divergence / limitation / unknown / freshness Claim supported / claim explicitly not supported Owner / reviewer / expiry / correction reference
«روی iPhone تست شد» فاقد مدل، OS، Build، نصب، شبکه، Locale، State و Oracle است. «در Chrome سبز بود» نیز Engine و Platform و Scope را نمیگوید. Evidence باید آنقدر دقیق باشد که تصمیمگیر بفهمد نتیجه به کدام جمعیت قابلتعمیم نیست.
از Evidence تا تصمیم پوشش
CoverageDecision DecisionID / release or change scope Supported-population snapshot + facts-as-of Risk / consequence / exposure / uncertainty Required surface-runtime combinations Selected tiers + mandatory seeds + exclusions Evidence references + confidence + unknowns Cost/queue/time/access constraints Option chosen + alternatives rejected + rationale Residual risk owner + decision authority Stop/rollback/reopen trigger + review date
QA میتواند Evidence فراهم کند و ناسازگاری را به چالش بکشد، اما بهطور خودکار مالک بودجهٔ دستگاه، Support policy، پذیرش ریسک، حریم خصوصی یا Release نیست. تصمیم باید صاحب اختیار و dissent ثبتشده داشته باشد. «همهٔ دستگاهها را تست میکنیم» هم برنامه نیست؛ مجموعهٔ دستگاهها نامتناهی و در حال تغییر است.
آزمایش مستقل: شعارهای درستنما در برابر ۴۰۸ کنترل
برای جلوگیری از یک مقالهٔ صرفاً توصیهای، یک Validator قطعی و بدون وابستگی روی Node.js ۲۴.۱۸.۰ اجرا شد. Fixture کاملاً ساختگی SYN-CLIENT-PLATFORM-MATRIX-01 پنج عبارت آشنا داشت: Web کنترلشده است، Mobile تکهتکه است، Device واقعی لازم است، Appium مشترک است و همهٔ دستگاهها باید پوشش داده شوند. یک بررسی سطحی فقط وجود این عبارتها را سنجید و خروجی گمراهکنندهٔ زیر را داد:
MOBILE_TESTING_ALWAYS_MORE_COMPLEX_WEB_CONTROLLED_READY
ممیزی مستقل، دقیقاً ۴۰۸ کنترل یکتای group-qualified را در ۲۲ گروه Surface، identity، support، runtime، distribution، device، input، capability، lifecycle، state، network، resource، accessibility، locale، security، automation، fidelity، evidence، decision، observability، governance و limits خواست. Fixture شعاری هیچیک را نداشت و نتیجه شد:
HOLD-408 NO_REAL_TARGET_PASS
قانون دوم جداگانه تأیید کرد هیچ Product، Organization، User، Device، Payment یا Outcome واقعی در آزمایش نیست. بعد همهٔ ۴۰۸ کنترل ساختگی با کلید یکتا پر شدند؛ assertion نیز هم تعداد و هم uniqueness را کنترل کرد و خروجی اصلاحی به این شکل بود:
READY_FOR_CLIENT_PLATFORM_MATRIX_REVIEW-0
این خروجی فقط کاملبودن ساختاری Fixture را ثابت میکند؛ نه درستی Requirement یا Oracle، کفایت دستگاهها، دسترسپذیری/امنیت، پوشش بازار، نبود defect، کیفیت محصول، هزینه، رضایت کاربر یا آمادگی Release. همین محدودیت بخشی از آزمایش است.
آزمایشگاه آفلاین فارسی برای Checkout چندسطحی
آزمایشگاه پیشنهادی هیچ شبکه، PSP، بانک، کاربر، پرداخت یا پول واقعی ندارد. Surfaceها شامل Responsive Web، PWA، Android Native و iOS Native ساختگیاند؛ Backend فقط یک Stub محلی با Order، PaymentAttempt، Callback، Ledger و Reconciliation جعلی است. مبلغ canonical برابر IRR ساختگی است و نمایش تومان فقط با برچسب تبدیل میشود.
SYN-CLIENT-CHECKOUT-01 Surfaces: WEB-R12 | PWA-R12 | ANDROID-A7 | IOS-I7 Data: fictional Order/Attempt/PSP-Stub/Callback/Ledger Locale: fa-IR + RTL; Persian/Arabic/Latin digits; ی/ي; ک/ك; ZWNJ Money: fictional IRR canonical; labelled display-only toman Time: UTC event; Asia/Tehran view; Jalali presentation-only Faults: offline; timeout-before/after-fake-commit; duplicate/late/reordered callback Lifecycle: tab discard; service-worker restart; background; termination; restore No: network, Production, real person/device/company/payment/money/bank/PSP/outcome
Oracle مشترک میگوید هر Command یک شناسه دارد، Retry اثر تکراری نمیسازد، نتیجهٔ نامعلوم تا Reconciliation به موفقیت جعل نمیشود و نمایش فارسی State سرور را تغییر نمیدهد. Oracle اختصاصی وب Cache/version و Tab restore را میسنجد؛ PWA Service Worker update را؛ Android/iOS نصب، Background/termination و state restoration را. این تفکیک نشان میدهد Domain risk میتواند مشترک و Platform evidence متفاوت باشد.
سناریوی نمونه؛ یک تغییر کوچک، چهار مسیر شاهد
| تغییر ساختگی | شاهد مشترک | شاهد وب/PWA | شاهد Native |
|---|---|---|---|
| افزودن Retry پرداخت | API contract + idempotency fault test | refresh/tab close/cache/version | background/termination/deep return |
| نمایش تومان | IRR canonical و conversion rule | Browser locale/input/bidi | OS formatter/keyboard/accessibility |
| تغییر Error copy | state/error vocabulary | responsive/zoom/screen reader | font scale/rotation/AT tree |
| SDK تحلیل | event schema/minimization | consent/storage/blocking | permission/lifecycle/binary impact |
یک E2E بزرگ که چهار مسیر را تکرار کند، عیبیابی کند و دادهٔ واقعی بخواهد لزوماً ارزشمندتر نیست. شواهد مشترک را در لایهٔ پایدار بگذارید و فقط تفاوت Runtime را روی Surface مربوط بسنجید.
Observability و Correction پس از انتشار
Matrix پیش از Release منجمد نمیشود. Crash/ANR، Web error، update failure، performance distribution، support signal و adoption نسخه میتوانند فرضهای پوشش را رد کنند. Telemetry باید حداقلی، دارای هدف، retention و دسترسی کنترلشده باشد و Segmentهای کمنمونه یا غایب را «بدون مشکل» تلقی نکند.
CorrectionRecord Original evidence/claim/decision IDs New observation + source + population + window Contradiction or scope change Affected surfaces/builds/users (bounded) Immediate containment Matrix/test/support-policy change Owner / approver / effective time Superseded artifact + notification + revalidation
ویرایش خاموش Test report، Support matrix یا نتیجهٔ قبلی، زنجیرهٔ تصمیم را میشکند. Correction باید مرجع قدیم را حفظ و محدودهٔ اثر را اعلام کند.
معیارهای سلامت Matrix و ضدشاخصها
| معیار | برای چه تصمیمی؟ | ضدشاخص |
|---|---|---|
| درصد Surfaceهای دارای identity تازه | آیا نتیجه قابلردیابی است؟ | زمان نگهداری رکورد |
| Riskهای دارای ترکیب و Evidence | شکاف پوشش چیست؟ | تعداد ترکیب/Run خام |
| زمان کشف incompatibility | بازخورد کجا کند است؟ | false fail و triage time |
| خطای تولید به تفکیک segment | فرض ماتریس کجا رد شد؟ | نمونهٔ غایب و privacy cost |
| عمر Evidence تا expiry | کدام شاهد کهنه است؟ | هزینهٔ اجرای مجدد |
| Correction lead time | سیستم چقدر یاد میگیرد؟ | تغییر خاموش و reopen |
تعداد Device، Test case، Browser یا Automation pass هدف نیست. افزایش بیحد آنها میتواند Queue و نگهداری را بالا ببرد و Critical risk را پنهان کند.
ضدالگوهای تفاوت تست وب و موبایل
- وب یعنی Desktop، Mouse، برق و اینترنت پایدار؛
- موبایل همیشه پیچیدهتر، گرانتر و تخصصیتر است؛
- Native، Hybrid، Cross-platform و PWA برچسبهای کافیاند؛
- نام Browser بدون Engine/OS/version؛
- نام OS بدون WebView/Build/device؛
- یک Emulator یا گوشی شخصی نمایندهٔ بازار است؛
- Device farm همان Market coverage است؛
- تست روی همهٔ دستگاهها هدف عملی است؛
- Analytics تنها منبع Support matrix است؛
- Pairwise همهٔ interactionها را پوشش میدهد؛
- Permission granted یعنی قابلیت سالم است؛
- وب Sensor و Background ندارد؛
- PWA دقیقاً مانند Native است؛
- Service Worker همیشه اجرا میماند؛
- Simulator برای Battery و Performance کافی است؛
- شبکهٔ ضعیف فقط مسئلهٔ موبایل است؛
- FPS بالا، Load performance سرور را ثابت میکند؛
- Screenshot، دسترسپذیری را ثابت میکند؛
- یک ابزار Automation، یک Strategy مشترک میسازد؛
- سبزشدن Retry، flaky را حل کرده است؛
- Release build با Debug نتیجهٔ یکسان دارد؛
- پنهانکردن دکمه Authorization است؛
- Log کامل همیشه Evidence بهتر است؛
- تعداد Run/Device معادل Coverage و کیفیت است؛
- QA بهتنهایی مالک Support policy و Release risk است؛
- گزارش قبلی را میتوان بیردپا اصلاح کرد.
چکلیست مالک Client Platform Matrix
- SurfaceID، Artifact family، Build و digest ثبت شدهاند؟
- Runtime شامل OS، Browser/Engine یا WebView است؟
- مسیر Distribution، install، update و migration معلوم است؟
- Support policy تاریخ، منبع و Unsupportedها را دارد؟
- Critical journey و consequence به Risk وصلاند؟
- Tierها و Seedهای اجباری rationale دارند؟
- دادهٔ Analytics با Support/Contract/Exclusion bias تکمیل شده؟
- Viewport، window، orientation و fold در دامنهٔ لازماند؟
- Touch، pointer، keyboard و فناوری کمکی جدا دیده شدهاند؟
- Permission state، hardware absence و fallback تعریف شده؟
- Lifecycle و state restoration Oracle دارد؟
- Offline/cache/sync/conflict/idempotency پوشش دارد؟
- Network profile و محدودیت شبیهسازی ثبت شده؟
- Client/Server/End-to-end performance جدا هستند؟
- Release build روی سختافزار لازم سنجیده شده؟
- فارسی/RTL/digit/money/time قرارداد روشن دارد؟
- امنیت و privacy به Surface و data flow متصلاند؟
- Automation Claim و Claim limit دارد؟
- Emulator/Simulator/Device/field Fidelity ثبت شده؟
- Evidence به Build/runtime/data/oracle/attempt متصل است؟
- FAIL/ERROR/SKIPPED/INCONCLUSIVE از هم جداست؟
- Raw evidence کمینه، redact و دارای retention است؟
- Unknown و known divergence حذف نشدهاند؟
- Residual risk و decision authority نامگذاری شدهاند؟
- هزینه، صف و دسترسی Device farm بررسی شده؟
- مسیر جایگزین برای محدودیت دسترسی ایران آزموده شده؟
- Telemetry bias و کاربران غایب در تحلیل آمدهاند؟
- Expiry، reopen، rollback و Correction تعریف شدهاند؟
Pilot سیروزه برای ساخت ماتریس
| بازه | کار | خروجی | شرط توقف |
|---|---|---|---|
| روز ۱ تا ۵ | Inventory Surface/Artifact/Runtime/Support | ClientSurfaceRecord و Unknownها | Build یا owner نامعلوم |
| روز ۶ تا ۱۰ | Risk/Journey/Population و Tier | Matrix v0 + mandatory seeds | Risk بدون decision owner |
| روز ۱۱ تا ۱۵ | Capability/Lifecycle/Network/Locale | Scenario و Oracle contracts | داده یا Permission پرخطر |
| روز ۱۶ تا ۲۰ | Automation/Fidelity/Evidence | Coverage map و Evidence schema | Release/target mismatch |
| روز ۲۱ تا ۲۵ | آزمایشگاه آفلاین و failure injection | Attempt-preserving results | اتصال ناخواسته به سیستم واقعی |
| روز ۲۶ تا ۳۰ | Review، Decision و correction drill | Matrix v1 + owners + expiry | ادعای Release/quality بدون اختیار |
این Pilot بدون کاربر، دستگاه، محصول، پرداخت یا Outcome واقعی نیز میتواند ساختار را تمرین کند. برای تصمیم واقعی باید Artifact، جمعیت، Evidence و اختیار واقعی با کنترلهای امنیت/حریم خصوصی جایگزین Fixture شوند.
جمعبندی؛ از دوگانهٔ وب/موبایل به تصمیم قابلاصلاح
تفاوت تست وب و موبایل واقعی است، اما در سه کلیشهٔ fragmentation، gesture و شبکه خلاصه نمیشود. تفاوت در Artifact و Runtime، توزیع و Update، Device و Input، Capability و Permission، Lifecycle و State، Storage/Offline، Resource، امنیت و شواهد لازم ظاهر میشود. بعضی ریسکها مشترکاند و باید در لایهٔ Domain/API پوشش داده شوند؛ بعضی فقط روی Runtime و سختافزار مربوط معنا دارند.
خروجی حرفهای فهرست بلند Device یا یک جدول Browser نیست؛ زنجیرهای است از Surface → Runtime → Support population → Risk → Combination → Evidence/Fidelity → Decision → Telemetry → Correction. این زنجیره نشان میدهد چه چیزی را سنجیدهاید، چه چیزی را عمداً نپوشاندهاید و چه رویدادی تصمیم را دوباره باز میکند.
سوالات متداول
آیا تست موبایل همیشه سختتر و پرهزینهتر از تست وب است؟
خیر. هزینه و پیچیدگی به Surfaceهای پشتیبانیشده، تعداد Runtime/Device/Browser، قابلیتها، سطح Fidelity، ریسک و نرخ تغییر بستگی دارد. وب چندEngine با PWA/Offline و ورودیهای گوناگون ممکن است از یک اپ تکپلتفرمی محدود پیچیدهتر باشد. عدد هزینه را از Matrix و TCO محلی بسازید.
برای اپ Hybrid باید تست وب بنویسیم یا تست Native؟
هر دو، اما براساس مرز واقعی. منطق Web و rendering در WebView، Bridge/Plugin، Permission و Lifecycle نیتیو، Package/Update و API هرکدام Claim و ابزار خود را میخواهند. برچسب Hybrid کافی نیست؛ نسخهٔ Container، WebView، Plugin و Build را ثبت کنید.
چه تعداد دستگاه و مرورگر برای تست کافی است؟
عدد جهانی وجود ندارد. از Support policy، جمعیت، Risk، مرز نسخهها، Crash/Support و قابلیت خاص Tier بسازید؛ سپس با Partition/Pairwise کم کنید و ترکیبهای پرپیامد را Seed اجباری نگه دارید. کفایت یک تصمیم زماندار با Unknown و residual risk است، نه درصدی از «کل بازار».
آیا Emulator یا Simulator میتواند جای دستگاه واقعی را بگیرد؟
برای بازخورد سریع، تنوع OS/Viewport و بسیاری از Flowها عالی است، اما Performance واقعی، Battery، thermal، بعضی Sensorها، OEM policy و حس ورودی را نمایندگی نمیکند. Claim تعیین میکند کدام محیط لازم است؛ دستگاه واقعی نیز نمایندهٔ همهٔ بازار نیست.
بهترین ابزار مشترک اتوماسیون وب و موبایل چیست؟
بدون دانستن Surface، Runtime، تیم، CI، Skill، قابلیت، Fidelity و TCO پاسخ معتبری وجود ندارد. نخست Claimها را میان Unit/Component/API/Browser/Native تقسیم کنید؛ سپس دو یا سه گزینه را با Fixture محلی، failure injection، false result، زمان triage و هزینهٔ نگهداری ارزیابی کنید. اشتراک Vendor یا زبان بهتنهایی مزیت نیست.

