با گذشت زمان، تکنولوژی و نرمافزارها بخشهای بزرگتری از زندگی ما را فرا میگیرد. خواه غذا خوردن باشد، خواه پرداخت کردن قبوضمان. این وابستگی شدید ما به نرمافزارها به این معناست که اشتباه کردن مهندسین نرمافزار در این نرمافزارهای حیاتی، میتوانند به هزاران و چهبسا میلیونها نفر خسارت وارد کنند و این در فضای رقابتی امروز به معنای از دست دادن مشتری است. برای جلوگیری از چنین خسارتهایی، فرایندهایی تحت چتر تضمین کیفیت (Quality Assurance یا QA) به جمع فرایندهای توسعه نرمافزار اضافه شده است که هدف آن، تضمین این است که نرمافزاری بدون اشکال را به کاربرانمان تحویل دهیم.
در این سری مطالب مرتبط با QA، به توضیح و معرفی فرایندهایی میپردازیم که با کمترین هزینه، بیشترین اطمینان از کیفیت نرمافزار را به ما ارائه میدهند. یکی از این فرایندها، فرایند تستنویسی است.
تستنویسی، نوشتن کدی است که کد (اصلی) محصول را تست کند.
تابعی را تصور کنید که عملیاتی شامل جمع و تفریق چند عدد را انجام میدهد. با فرض اینکه پیادهسازی این محاسبه ممکن است پیچیده باشد (و برای مثال برای قیمت یک سرویس استفاده شود)، برنامهنویس معمولاً از طریق مشخص کردن ورودیها، دستی حساب کردن خروجی و مقایسه آن با خروجی تابع، از صحت کار یک تابع اطمینان حاصل میکند. در صورتی که فرایند محاسبه در تابع ما تغییر کند، برنامهنویسی که تغییرات را اعمال کرده هم نیاز دارد دوباره با مقایسه نتیجهای که خود به دست آورده با خروجی تابع از صحت کار آن اطمینان پیدا کند.
تا به اینجای کار به نظر نیازی به تستها نیست. با این حال، مسئله زمانی ایجاد میشود که تحت فشار کاری، ممکن است چنین صحتسنجیای انجام نشود یا انجام آن زمان ارزشمندی از توسعهدهندگان بگیرد. همچنین ممکن است یک تابع به تنهایی درست کار کند اما در فرایند دیگری که از آن استفاده شده است خطایی ایجاد شود. در صورتی که به جای یک انسان، یک تست اتوماتیک وجود داشته باشد که با هر تغییر در نرمافزار، هر تابع را به شکل جدا و هر ویژگی نرمافزار را به شکل جدا تست کند، امکان اطمینان بیشتر از صحت کار نرمافزار بدون هزینه اضافه قابل توجه ایجاد میشود.
تستنویسی در کنار استفاده از قابلیتهای CI/CD به ما اجازه میدهند به شکل خودکار نرمافزارمان را قبل از هر پیادهسازی و پس از هر تغییر بررسی کنیم.
حال که اهمیت تستنویسی و تستهای اتوماتیک را در توسعه نرمافزار دریافتیم، سوال دیگری مطرح میشود: «تستنویسی چگونه در روند پیشین توسعه نرمافزار من جای میگیرد؟» پاسخ این سوال ساده است: در ابتدای آن.
توسعه تستمحور (Test-Driven Development یا TDD) روشی است که در آن بر پایه نیازهای مشتری، تستهایی نوشته میشوند که تنها در شرایطی موفق میشوند که آن نیاز در نرمافزار پیاده شده باشد. پس از نوشتن تستها، کدنویسی بر روی نرمافزار آغاز میشود و سعی در آن است که با کمترین میزان کدنویسی، تستها موفق (pass) شوند. این روش در کنار ایجاد تست برای ویژگیهای جدید، با به حداقل رساندن حجم کد ممکن احتمال خطا را کاهش میدهد.
نکته: در فرایند تضمین کیفیت نرمافزار (SQA) انواع مختلفی از تستها وجود دارد. (بیشتر بدانید) در این مطلب منظور از نوشتن تست، Unit Testing و Integration Testing است.
احتمالاً در صورتی که تا به حال تست ننوشته باشید، یکی از پرسشهای بزرگ در ذهن شما این باشد که تا چه حدی جزئیات نرمافزار را تست کنید؟ آیا تست کردن یک تابع با تست کردن یک ویژگی تفاوت دارد؟
پاسخ این سوال را با توجه به تجربه شخصی نویسنده از فریمورک لاراول میدهیم: تستهای خودکار به دو دستهی Unit Test و Integration Test (یا Feature Test) تقسیم میشوند. در اینجا، تستهای مرتبط با یک تابع یا جزء کوچکی از نرمافزار Unit Test و در کنار هم قرار گرفتن آنها Feature Test نامیده میشود. در فرایند توسعه نرمافزار، نوشتن هر دو نوع این تستها برای عیبیابی راحتتر ضروری است.
با توجه به اینکه هر زبان برنامهنویسی روش خود را برای تست ایجاد کرده است و فریمورکهای مختلف هم روش مختص به خود را برای تستنویسی دارند، در این مطلب به مفاهیم تستنویسی، TDD و انواع تستها بسنده کردیم. پیشنهاد میکنیم در صورتی که برای زبان و فریمورک خودتان منبع آموزشی برای تستنویسی میشناسید، در نظرات این مطلب معرفی کنید و برای معرفی این مفاهیم به سایرین، این مطلب را به اشتراک بگذارید.
تصاویر از John Schnobrich در Unsplash