خلاصه: کج فهمیهای زیادی در مورد تست اکتشافی(Exploratory Testing) وجود دارد. در برخی از سازمانها تستهای اکتشافی به صورت غیر حرفهای و بدون ساختار انجام میشود. هیچ گونه آمادگی، استراتژی تست، طراحی تست و یا تکنیکی برای Coverage وجود ندارد. این امر باعث بروز نقاط کوری در تست مانند مشکلات رگرسیون میشود. در این مقاله در رابطه با این موضوع که چگونه میتوان تست اکتشافی را ساخت یافتهتر کرد صحبت خواهیم کرد.
سازمانها در تلاش های تست خود، تست اکتشافی را به میزان بیشتری اعمال می کنند. چنین چیزی به خوبی با اتوماسیون تست مطابقت دارد و با Agile و DevOps به طور منعطفی کار میکند. اما کج فهمیهای زیادی در باره تست اکتشافی وجود دارد. در برخی از سازمانها دیده مبشود که تست اکتشافی به صورت غیر حرفهای و بدون ساختار انجام میشود. در این مقاله، درباره موردی که در آن یک سازمان از تست اکتشافی بی ساختار به تست اکتشافی ساخت یافته، دست مییابد بحث خواهیم کرد.
چالشهای تست اکتشافی بدون ساختار
سازمانی، نرمافزار سفارشی ایجاد میکند. آنها در یکی از پروژههای خود، برنامهای برای کارکردن دستگاههای خانگی متصل به اینترنت اشیاء ایجاد کردند. تیم یک اپلیکیشن ترکیبی تولید نمود(وبسایتی ایجاد کردند که با بهرهگیری از یک پوسته میتوانست به صورت یک برنامه استفاده شود). برنامه برای جدیدترین نسخههای Android و iOS توسعه یافته بود، اما Windows Phone در آن پشتیبانی نمیشد.
اگر چه کیفیت مهم بود، اما تیم تولید کننده هیچ تستری نداشت. توسعهدهندگانی که نرم افزار را ساخته بودند، کار خود را با استفاده از Unit Testing آزمودند و سپس کد توسط توسعهدهنده دیگری مورد بررسی قرار گرفت. بعد از Unit Testing و بازبینی کد(Code Review)، نرمافزار جدید بر روی محیط آزمایشی جداگانهای نصب شد و یک توسعهدهنده دیگر تست Functional بر روی آن انجام داد. در این تست، آنها عمدتا بر روی Happy Path متمرکز شدند و شرایط خطا یا شرایط غیر منتظره را تست نکردند. در این تست ساختار درستی نیز وجود نداشت.
از برخی جهات این تست را میتوان، تست اکتشافی نامید، چرا که توسعهدهنده تست را آغاز کرده و با توجه به خروجی آن تصمیمگیری میکند که Test Case بعدی چه باشد. با این حال، تدارکی(Preparation) وجود ندارد. توسعهدهنده استراتژی تست نداشت و از تکنیکهای طراحی تست یا تکنیکهای Coverage استفاده نکرد. این امر باعث بروز نقاط کوری در تست مانند مشکلات رگرسیون شد.
پس از تست Functional، تیم یک تست Integration انجام داد تا ببیند آیا سیستم با سیستمهای عرضه شده توسط سایر تامین کنندگان کار میکند یا خیر. این تست نیز خیلی ساختارمند نبود و فقط Happy Path را تست کرد. پس از تست یکپارچهسازی(Integration)، یک تست پذیرش(Acceptance) در محیط جداگانه توسط افرادی که اصطلاحا تسترهای سمت مشتری بودند انجام گرفت. این افراد میتوانستند کاربران واقعی یا کارکنان نیز باشند. این جلسات تست به نوعی شکار باگ(Bug Hunting) بود، اما باز با Preparation و ساختار کمتری صورت گرفت. این که چه چیزی تست شده است نیز نامشخص بود. در این بازه زمانی از اتوماسیون تست استفاده نشد و تست رگرسیون نیز با استفاده از یک چک لیست استاندارد به صورت دستی انجام شد. توسعهدهندگان ترجیح میدادند وقت خود را بر روی Featureهای جدید صرف کنند تا روی تست رگرسیون. بنابراین اغلب تست رگرسیون به درستی انجام نمیشد یا گاهی اوقات اصلا انجام نمیشد. البته این موضوع ریسک مشکلات رگرسیونی را نشان داد که بسیار جدی بود، چرا که برنامه در بسیاری از دستگاهها و محیطهای مختلف مورد استفاده قرار گرفت.
یک حرکت برای بهبود تست این بود که به نسخه بالاتر سیستم عامل ارتقا دهند که باعث شد برنامه هر بار که کاربر سعی در باز کردن آن داشت Crash کند. اگر تست به صورت ساختاری انجام میشد، باگ و همچنین علت اصلی(Root Cause) میتوانست در گام های اولیه مشخص شود اما این باگ خاص در Unhappy Path بود، که تیم آنرا در نظر نگرفته بود. چیزهایی باید تغییر میکرد.
حرکت به سمت تست اکتشافی ساخت یافته
در ابتدا تیم نیازمندیها بهبود یافت. سپس مشتری لیستی از Featureها(امکانات) و شرایطی که قبل از انتشار نسخه جدید بایستی بررسی میشد را ایجاد کرد. در نهایت، یک تستر برای بهبود پوشش تست(Test Coverage) به کار گرفته شد.
تستر، تست اکتشافی ساخت یافته را معرفی کرد. او ریسک محصول را همراه با دیگر ذینفعان، به طوری که برخی از نقاط کور به صراحت بیان شده باشد، ارزیابی کرد. همچنین فهرستی از چیزهایی که باید برای هر Feature، در طول Happy Path و Unhappy Path تحت تست قرار گیرد، ایجاد نمود. او از تیم پرسید که اگر سرویس خاصی در دسترس نباشد یا اینکه برخی عناصر قابل دسترسی نباشند کاربر با چه تجربهای مواجه خواهد شد. بعلاوه برای برخی از قسمتهای بسیار پیچیده برنامه، Test Scriptهایی را با جزئیات بالا نوشت. تستر همچنین از روشهای طراحی تست و تکنیکهای Coverage استفاده کرد. ایدههای تست را در نقشههای ذهنی(Mind Map) مستند کرد که موجب صرفهجویی مناسبی در زمان و آسانتر شدن نگهداشت، نظارت و انعطافپذیری بیشتر نسبت به یک شیت یا سند شد.
اکثر تستهای واقعی توسط تستر انجام شد، اگر چه سایر اعضای تیم نیز مشارکت داشتند. یکی از جنبه های مهم تست این بود که علاوه بر ارزیابی ریسک محصول، نتیجه تستهای قبلی نیز برای تصمیمگیری درمورد اینکه تست بعدی چه باشد، مورد استفاده قرار گرفت. هنگامی که یک باگ خاص پیدا میشد، میتوانست نشانهای از این باشد که همان نوع باگ ممکن است در بخش دیگری از نرمافزار رخ داده باشد یا هنگامی که بخش خاصی از نرمافزار به خوبی کار میکرد میتوانست نشانهای از این باشد که همان قسمت را میتوان در جایی دیگر کمتر زیر تست قرار داد.
بنابراین هیچ استراتژی تست ثابتی یا طرحی جامع برای آنچه که باید تحت تست واقع شود، وجود نداشت اما تستها براساس ریسکها و نتیجه تستهای دیگر تعیین میشد. ما این را یک استراتژی تست مداوم(Continuous Test) مینامیم. هر دو استراتژی تست و Test Plan فعالیت یک باره در پروژه انجام نبود بلکه یک فعالیت مداوم بود که تست را بسیار انعطافپذیرتر میکرد.
یکی دیگر از معیارها، معرفی سیستم اتوماسیون تست موبایل بود. انواع راهکارهای اتوماسیون تست موبایل چه به صورت منبع باز(Open Source) و چه به صورت ابزارهای تجاری نیز وجود داشت. در این پروژه ما تصمیم گرفتیم از Cucumber استفاده کنیم تا کاربران را برای اضافه کردن یا تنظیم سناریوهای تستِ نوشته شده به صورت متن ساده(Plain Text) آماده سازیم. Web Driver ترکیبی از دو ابزار، Selenium و Appium بود تا تست Cross Platform(چند سکویی) را با توجه به iOS و اندروید پشتیبانی کند. این چارچوب به گونهای تنظیم شده بود که در صورت لزوم به طور عمومی و آسان، به صورت مجدد استفاده(Reuse) شده و یا بسط(Expand) یابد.
Regression Test Caseهای اتوماتیک از دو منبع آمدهاند. منبع اول زیر مجموعهای از تستها بود که در گذشته انجام شده بود. خودکار سازی تمام تستها باعث میشد که تست رگرسیون بیش از حد بزرگ باشد که زمان و بودجه را برای ایجاد، نگهداری و اجرای آن افزایش میداد، بنابراین ترفند این بود که Coverage را با اندازه مجموعه تست رگرسیون به تعادل برسانیم. در این میان یک مجموعه تست رگرسیون کوچک و خودکار با Coverage بالا ارجحیت داشت. منبع دوم Test Caseها فهرستی از Featureها و شرایطی بود که باید بررسی میشدند. مزیت خودکار کردن این لیست این بود که تیم میتوانست به مشتری تضمین دهد که تمام موارد موجود در لیست، تحت تست قرار گرفتهاند. پس از دِمو کردنِ تست رگرسیون اتوماتیک، مشتری اعتماد بیشتری نسبت به استقرار انتشارهای جدید از خود نشان میداد.
از آنجایی که تیم دو هفته برای انتشار هر نسخه کار میکرد، تست رگرسیون خودکار هر دو هفته انجام میشد. تیم همچنین متوجه شد که به علت تست رگرسیون خودکار، زمان بیشتری برای ساختن Featureها دارد. قبل از اینکه مجموعه تست رگرسیون خودکار شود، تیم زمان زیادی را صرف انجام تست رگرسیون ناکامل به صورت دستی میکرد.
هم مشتری و هم تیم از نتایج به دست آمده راضی بودند. پس از انجام تستهای اکتشافی ساخت یافته و تست رگرسیون خودکار(در نقاط دیگر برنامه یا وب سایت) نقیصه عمدهای وجود نداشت.
درسهای آموخته شده
من چهار درس از این اتفاقات آموختم:
- اولین نکته وجود تفاوت بین تست اکتشافی ساخت یافته و بی ساختار است. در تست اکتشافی ساخت یافته، شما یک استراتژی تست دارید و علاوه بر آن Test Planning انجام میدهید. اگرچه استراتژی و برنامهریزی باید انعطاف پذیر باشد، عاقلانه نیست که یک استراتژی تست بزرگ را روبروی خود قرار داده و به آن بچسبید. در طول فرآیند باید از خود بپرسیم چه چیزی را چگونه تست کنیم.
یکی دیگر از جنبههای تست اکتشافی ساخت یافته، استفاده از تکنیکهای طراحی تست و تکنیکهای Coverage است. این تکنیکها به ارزش تست میافزایند اما باید با انعطافپذیری بیشتری مورد استفاده قرار گیرند. عدم داشتن دانش روی استراتژی تست، برنامهریزی تست، میتواند تکنیکهای طراحی تست و تکنیکهای Coverage را به یک ریسک تبدیل کند. - دومین موردی که آموختم این است که ما میتوانیم در صورت نیاز زمان کمتری را با عدم تولید Test Scriptهای دقیق در مستندسازی صرف کنیم. استفاده از ابزارهایی مانند نقشههای ذهنی به ساختن مستندات سبک وزنتر نیز کمک میکنند.
- سومین مورد این است که اتوماسیون تست مفید است اما پاسخی به تمام مشکلات ما نیست. هنوز هم دقت و تفکر در مورد اینکه باید چه چیزی به چه شکل تست و با چه روشی تست شود اهمیت دارد. باید قبول کنیم که ابزارهای امروزی موجود نمیتوانند تست را به طور کامل انجام دهند.
- مورد چهارمی که آموختم این است که تست هنوز هم یک هنر است. تسترهای خوب روشها، ابزارها و تکنیکهای آنرا میدانند و میدانند که این مهارتها باید در یک تیم حضور داشته باشند. دوره برخورداری از تستهای بزرگ و جداگانه حداقل در اکثر سازمانها سرآمده است، اما داشتن مهارتهای تست هنوز هم مورد نیاز است.
هنگامی که کیفیت را مهم تلقی کنیم، تیمهای تست باید تست اکتشافی ساختیافته را انجام دهند و این به مهارتهای حرفه ای تست نیاز دارد.