جمعه , ۷ اردیبهشت ۱۴۰۳

ضعف آفت‌کشها را در تست نرم‌افزار جدی بگیریم

Pesticide Paradox in Software Testing
Pesticide Paradox in Software Testing

چکیده: متاسفانه این مورد را تا کنون زیاد رویت کردم، که تسترها یا از ضعف‌های اجرای تست تکراری آگاه نیستند، یا فرصت Design و Implementation جدید ندارند، و یا واقعا تنبلی می‌کنند. به هر حال هر کدام از دلایل، نتیجه یکسانی به نام “تست تکراری” را به ارمغان می‌آورد. به همین دلیل تا پیامِ تکمیل شدن دیباگ به آنها می‌رسد، فورا تست قبلی را به صورت تکراری و بدون تغییر اجرا می‌کنند، و در صورت Pass شدن تست، Failure مورد نظر را با حالت Pass شده، Close می‌کنند.

احتمالا نام این مقاله برای برخی از شما نامانوس است. البته ممکن است آن دست از خوانندگانی که روی ISTQB مطالعه داشتند، با این موضوع آشنا باشند. چرا که در “هفت اصل اساسی تست نرم افزار”، موضوعی به نام “پارادوکس آفت‌کش‌ها(Pesticide Paradox)” یا “ضعف آفت‌کش‌ها” ذکر شده است.

  1. اما این اصل چه می‌گوید؟

احتمالا می‌دانید که آفات مزارع به مرور زمان در برابر یک آفت‌کش که به صورت دائم استفاده می‌شود، در نسل‌های بعدی خود مقاوم می‌شوند، و شما برای سری جدید سمپاشی نیاز به سموم جدیدتری دارید، که بدن آفت آمادگی مقابله در برابر آنرا نداشته باشد. این یعنی آفت در برابر آفت‌کش تکراری مقاوم شده است. همین موضوع در تست نرم‌افزار هم وجود دارد. مَخلصِ کلام در اصل “پاردوکس آفت‌کش‌” معتقد است که Failureها  در برابر تست‌های تکراری مقاوم می‌شوند، و دیگر به راحتی رخ نشان نمی‌دهند. خب شاید این موضوع عجیب به نظر برسد، چرا که Failure و عامل آن که باگ است، فاقد یک ساختار ژنتیکی و زنده هستند که مانند آفت توانایی تولید پادتن‌های مقاوم در برابر تست‌های تکراری را داشته باشند.

مساله پیش رو موضوعی نیست که توسط تست‌ها و باگ‌ها ایجاد شود. بلکه اصل موضوع “پاردوکس آفت‌کش‌” به دلیل فرآیند تست بروز می‌کند.

بیایید ببینیم در یک فرآیند معمولی تست چه اتفاقی رخ می‌دهد. فرض کنید که تستر هستید:

  • یک Feature را برای تست در اختیار شما می‌گذارند.
  • اجرای تست در Feature مذبور، یک Failure را به شما نشان می‌دهد.
  • شما Failure مشاهده شده را در قالب یک Bug Report به توسعه دهنده منتقل می‌کنید.
  • توسعه دهنده باگ مربوطه را رفع می‌کند.
  • توسعه دهنده، احتمالا برای اطمینان از رفع باگ(البته احتمالا) مراحل Bug Reproduction که به همراه داده‌های تست است را روی Feature مذبور مجددا تست می‌کند.
  • در ادامه اگر این تست Fail شود، مجددا توسعه دهنده روی Feature کار می‌کند، و این چرخه را آنقدر ادامه می‌دهد تا دیگر نتواند بر اساس Bug Report، باگ مورد نظر را ایجاد نماید.
  • پس از اینکه توسعه دهنده از موفقیت در تست خود اطمینان حاصل کرد آنرا در اختیار تستر می‌گذارد تا آنرا تائید نماید.

اکنون که به مرحله نهایی رسیدیم، اگر تستر همان تستی را که مراحل اجرای آن در Bug Report منعکس شده است را مجددا اجرا نماید، محتملترین نتیجه چه خواهد بود؟ به احتمالا بسیار بالا و نزدیک به ۱۰۰% تست پاس خواهد شد. فقط ممکن است برخی از مسائل محیطی منجر به Fail شدن چنین تستی شود. چرا که این تست قبلا توسط توسعه دهنده اجرا و Pass شده است(و فقط با احتمال بسیار کم ممکن است به خاطر تفاوت محیط تستر و توسعه دهنده Fail شود) و با احتمال بسیار زیاد باز هم Pass می‌شود.

پس یک تست تکراری در نگاه اول تست بی ارزشی می‌نماید.

  1. تست تکراری بی ارزش نیست

با خواندن پاراگراف بالا، احتمالا بسیاری از شما احساس می‌کنید تست تکراری فاقد ارش است!

خیر. تست تکراری می‌تواند بسیار هم ارزشمند باشد، ولی در صورت Pass شدن نباید صرفا به آن اکتفا کرد.

اما ارزش یک تست تکراری چیست؟

تکرار یک تست که همه چیز آن آماده است به نسبت طراحی یک تست جدید که ممکن است مراحل جدیدی داشته و البته قطعا هم داده‌های آن تغییر کرده است، بسیار ارزانتر و کم هزینه‌تر است. شما به عنوان یک تستر باید فرض را بر این بگیرید که باگ هنوز رفع نشده، و شما باید با تست کردن و عدم رویت Failure از این موضوع مطمئن شوید.

حالا که فرض را بر وجود Failure گذاشته‌اید، ترجیح می‌دهید از روش‌های ارزان و کم زمان برای استخراج Failure بهره بگیرید یا گران و زمانبر؟ هیچ موجود زنده‌ای(حتی در برخوردهای غریزی) ولو حشرات و گیاهان هم تمایل ندارند، یک کار را از راه سختش انجام دهند.

دلایل منطقی که شما باید بر اساس آن تست‌های قبلی خود را تکرار کنید(اما به آنها اکتفا نکنید) عبارتند از:

  • هزینه اجرای پایین و اینکه ممکن است توسعه‌دهنده بعد از دیباگ، تست را مجددا اجرا نکرده باشد و به هر دلیلی تمایل داشته باشد این کار توسط تستر انجام شود. احتمال این موضوع اصلا پایین نیست.
  • هزینه اجرای پایین و اینکه شاید حتی توسعه دهنده تست را مجددا اجرا کرده باشد، و آن تست هم Pass شده باشد. اما با اجرای مجدد در محیط تستر، که محیط تائید شده تست است، نتیجه اجرا برابر با Fail باشد. دلیل چنین امری می‌تواند تفاوت میان محیط‌های اجرای تست(محیط اجرای تست برای تستر و محیط اجرای تست برای توسعه‌دهنده)، و یا نابلدی در اجرای تست توسط توسعه‌دهنده باشد، که یک False Negative را به ارمغان آورده است.
  • هزینه اجرای پایین و اینکه شاید واقعا باگ رفع شده باشد، اما در نسخه Testable که در محیط تست لانچ شده است، کارهای دیگری هم انجام شده است، که مجددا به دلیل Side Effect همان باگ یا باگ‌های دیگری را ایجاد کرده است.

سه دلیل متفاوت در بالا همگی حول هزینه پایین اجرای تست تکراری اشتراک دارند. یعنی دلیل اصلی اجرای تست تکراری، هزینه پایین آن است. چرا که تست‌ها از قبل آماده شده، و دیگر نیازی به Design(مثلا Test Case جدید) یا Implementation(مثلا تولید  Test Scriptجدید-صرفا در تست اتوماتیک و  Test Data جدید) جدید ندارد.

یک نکته مهم این است که اگر به هر دلیلی خرق عادت شود، و اجرای تست تکراری از تست جدید پرهزینه‌تر شود(زمان بیشتری را به نسبتِ تستِ جدید به خود اختصاص دهد)، آنگاه اجرای تست تکراری دیگر معقول نخواهد بود، و بهتر است به سراغ تست‌های جدید بروید.

ارزش تست تکراری آنجا مشخص می‌شود، که پس از اجرا، قسمت تحت تست(SUT) را Fail کند. این یعنی: “نتیجه این تست Fail بود، و تستر با کمترین هزینه به این نتیجه نائل شد”. در اینجا دیگر نیازی به تست جدید نیست، چون باگ نتوانسته در مقابل همان تست تکراری مقاومت کند، و مجددا خود را نشان داده است. دقیقا مثل این است که آفت‌کش ما هنوز هم اثر دارد. وقتی آفتکش هنوز هم آفات را شکار کرده و از بین می‌برد، دیگر نیازی به آفت‌کش جدید نیست.

اما اگر نتیجه اجرای تست تکراری برابر با Pass بود چه؟

  1. آماده‌سازی تست‌های جدید

وقتی تست تکراری ما Pass شد، نباید صرفا به اجرای آن اکتفا کرد. از اینجا به بعد نوبت به اجرای تست جدید می‌رسد. تست‌هایی که باید Design و Implementation روی آنها انجام شود. البته معمول اوقات Design تست‌ها تغییری نمی‌کند، و صرفا Implementation آنها دگرگون می‌شود.

وقتی می‌گوییم Implementation آنها تغییر می‌کند، هم معمولا منظورمان تغییر در Test Data است. در این وضعیت حتی اگر تست‌ها اتوماتیک هم باشند، در صورت Data Driven بودن نیازی به تغییر در اسکریپت نیست، و صرفا باید محتوای فایل Data Sheet که در برگیرنده Test Data است را تغییر داد.

در موارد بسیار بسیار نادر ممکن است نیاز به طراحی Logical Test Caseهای جدید داشته باشیم. معمولا این موضوع در شرایطی بروز می‌کند که یک Business به طرق مختلفی قابلیت اجرا داشته باشد، که در این صورت پیشنهاد می‌شود، نه تنها برای Test Case قبلی داده‌ها را تغییر داده و اجرا نمایید، بلکه Test Case دیگری که Business را به شیوه متفاوتی تست می‌کند، به همراه Test Data آماده و Execute کنید.

متاسفانه این مورد را تا کنون زیاد رویت کردم، که تسترها یا از ضعف‌های اجرای تست تکراری آگاه نیستند، یا فرصت Design و Implementation جدید ندارند، و یا واقعا تنبلی می‌کنند. به هر حال هر کدام از این دلایل، نتیجه یکسانی به نام “تست تکراری” را به ارمغان می‌آورد. به همین دلیل تا پیامِ تکمیل شدن دیباگ به آنها می‌رسد، فورا تست قبلی را به صورت تکراری و بدون تغییر اجرا می‌کنند، و در صورت Pass شدن تست، Failure مورد نظر را با حالت Pass شده، Close می‌کنند.

پس موضوع ضعف آفت‌کشها را در تست نرم‌افزار جدی بگیرید، چرا که ممکن است سیستم هنوز مشکل داشته باشد، و شما صرفا باید تست خود را تغییر دهید.

ابوالفضل خواجه دیزجی

همچنین ببینید

Test Data Bottleneck

تنگنای داده های تست و راهکار آن

زمان زیادی برای یافتن کیس های مناسب برای داده های تست هدر می شود، چندین …

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *