شاید یک کاربر عادی اطلاعات زیادی از مراحل ساخت و توسعه نرم افزار نداشته باشد. ساختن برنامه کامپیوتری به این شکل نیست که یک نفر برنامه نویس تمام کدها را نوشته و بلافاصله محصول را منتشر میکند. یک نرم افزار استاندارد و بزرگ باید قبل از رسیدن به دست کاربر نهایی یک سری مراحل را پشت سر بگذارد. یکی از کارهای رایج در تولید نرم افزار، تست و آزمایش محصول میباشد و به جرات میتوانیم بگوییم که اهمیت آن کمتر از طراحی و توسعه محصول نیست. یکی از تستهای معروف در ساخت نرم افزار Unit Testing است. امروز میخواهیم درباره این صحبت کنیم که Unit Testing چیست و چه مفهومی دارد.
Unit Testing چیست؟
تست واحد (Unit Testing) یک مرحله از تست نرم افزار است که در آن بخشهای کوچک از یک برنامه (Units) یا کامپوننتهای مختلف یک نرم افزار تست میشوند. برنامه نویسان از Unit Test استفاده میکنند تا ببیند بازدهی برنامه آنها چیزی است که انتظارش را داشتند یا خیر. به عبارتی Unit Testing به برنامه نویس نشان میدهد که چقدر به طراحی اولیه نزدیک شده و برنامه او مطابق استانداردهای طراحی اولیه نرم افزار عمل میکند یا خیر . منظور از Unit کوچکترین بخش از برنامه است که قابل تست بوده و به طور معمول شامل چند ورودی و نهایت یک خروجی میشود. در برنامه نویسی رویه ای Unit میتواند یک تابع، Procedure یا حتی یک برنامه کوچک باشد. همینطور در برنامه نویسی شی گرا کوچکترین Unit یک متد بوده که میتواند به Class، Super class Abstract Class یا Child Class تعلق داشته باشد. بعضیها به اشتباه ماژول را هم یک یونیت در نظر میگیرند که درست نمیباشد چون خود ماژول از تعدادی یونیت تشکیل شده است. این روش آزمایش در هنگام نوشتن برنامه و معمولا توسط خود برنامه نویس به کار گرفته میشود. البته گاهی تیم بررسی کیفیت (QA) نیز این کار را انجام میدهند. Unit Testing یک بخش مهم در توسعه نرم افزار به حساب میآید. چون اگر به درستی اجرا شود میتواند کمک بزرگی به توسعه نرم افزار بکند. به این شکل که ایرادات و مشکلات برنامه در همان اول کار تشخیص داده شده و حل میشوند. فرض کنید حل کردن این مشکلات زمانی که پروژه ما بسیار بزرگ شده چقدر دردسرساز خواهد شد.
مراحل تست واحد (Unit Testing)
یک پروسه Unit Test به طور کلی به 3 بخش تقسیم میشود:
نقشه (Plan)
Cases و Scripts
Unit Test
Unit Testing فاز اول آزمایش برنامه بوده و در واقع اولین سطح از تست برنامه به حساب میآید. این روش یک تکنیک آزمایش White Box محسوب میشود. تست جعبه سفید یک متد است که صرف نظر از خروجی ای که برنامه تولید میکند، ساختار درونی آن را بررسی میکند. در مدلهایی مثل SDLC، STLC یا V Model قدم اول در آزمایش پروژه Unit Testing است و قبل از متدهای آزمایش دیگر مثل integration testing اجرا میشود. امیدواریم به یک درک کلی درباره اینکه Unit Testing چیست رسیده باشید.
Unit Test چطور انجام میشود؟
Unit Test به دو صورت دستی و خودکار انجام میشود. هرچند بیشتر مواقع از روش خودکار استفاده شده و این روش در اولویت است، اما تا زمانی که کار به بهترین شکل انجام شود مهم نیست که از کدام روش استفاده میکنید. در روش خودکار مراحل به این شکل دنبال میشوند:
برنامه نویس یک کد برای تست برنامه نوشته و آن را به پروژه اضافه میکند. این کد در آینده یعنی زمانی که برنامه منتشر میشود از داخل کدها حذف خواهد شد.
به طور کلی برنامه نویس از یک فریم ورک Unit Test برای بررسی وضعیت کدها استفاده میکند. این کار مزایای زیادی دارد، مثلا در مواقعی که Test شکست میخورد فریم ورک یک Log از این اطلاعات تهیه کرده و آن را در قالب یک گزارش ارائه میکند. بسته به شدت مشکلاتی که پروژه دارد، فریم ورک میتواند از اجرای تستهای بعدی جلوگیری کند.
ابزارهای Unit Test
ابزارهای زیادی برای Unit Test وجود دارند که چند مورد از آنها را در ادامه مشاهده میکنید:
Junit: یک ابزار رایگان برای پیاده سازی Unit Test در زبان برنامه نویسی جاوا است.
NUnit: یک فریم ورک متن باز برای تکنولوژی .Net میباشد.
EMMA: یک ابزار نوشته شده به زبان جاوا برای آنالیز و گزارش گیری است.
PHPUnit: به وسیله PHPUnit میتوانید در زبان محبوب PHP Unit Testing انجام دهید.
JMockit: یک ابزار عمومی Unit Testing با قابلیتهای بسیار متنوع میباشد.
در اکوسیستم جاوااسکریپت نیز ابزارهای مختلفی برای Unit Testing وجود دارد که فرایند تست را سادهتر و سریعتر میکنند. از جمله ابزارهای رایج تست واحد در جاوااسکریپت میتوان به موارد زیر اشاره کرد:
Jasmine: فریمورکی مبتنی بر BDD که امکان تست کدهای همگام و ناهمگام جاوااسکریپت را فراهم میکند.
QUnit: فریمورکی ساده و قدرتمند برای تست انواع کدهای جاوااسکریپت.
Mocha: فریمورکی منعطف که با استفاده از آن میتوان تستهای همگام و ناهمگام را اجرا کرد.
Tape: ابزاری سبک که خروجی تستها را در قالب TAP ارائه میدهد.
Karma: اجراکننده تست که امکان اجرای تستها در مرورگرهای واقعی را فراهم میکند.
مزایا و معایب روش Unit Testing
مثل تمام تکنولوژیهای روز دنیا، استفاده از Unit Testing هم یک سری مزایا دارد و یک سری معایب.
مزایای Unit Testing
بعضی از مهمترین مزایایی که به کمک Unit Testing به دست میآیند عبارتاند از:
Unit Test کمک میکند باگها در چرخه توسعه نرمافزار خیلی زودتر شناسایی شوند و در نتیجه هزینه و زمان رفع خطا به شکل قابل توجهی کاهش پیدا کند.
Unit Test درک بهتری از کدها به برنامهنویس میدهد و اعمال تغییرات یا ریفکتور کردن کدها را امنتر و سریعتر میکند.
اگر Unit Testing بهدرستی انجام شود، عملاً به مستندسازی پروژه کمک میکند؛ چون هر تست نشان میدهد انتظار ما از رفتار کد چیست.
Unit Test امکان استفاده مجدد از کدها و حتی تستها را در پروژههای دیگر فراهم میکند.
در پروژههای جاوااسکریپتی، Unit Testing یک مزیت مهم دیگر هم دارد:
با تست واحد میتوان توابع و ماژولهای مختلف را بهصورت مستقل بررسی کرد و بدون نگرانی از تأثیر منفی روی بخشهای دیگر برنامه، کد جدید به پروژه اضافه کرد.
وقتی بعد از مدتی دوباره به کدهای قدیمی جاوااسکریپت برمیگردیم، وجود Unit Test باعث میشود سریعتر متوجه شویم هر تابع چه ورودیای میگیرد و چه خروجیای باید تولید کند.
تقسیم یک پروژه بزرگ جاوااسکریپتی به بخشهای کوچک و قابل تست، پیدا کردن محل خطا را بسیار سادهتر میکند و زمان دیباگ را بهشدت کاهش میدهد.
معایب Unit Testing
در کنار این مزایا، Unit Testing محدودیتهایی هم دارد که نباید نادیده گرفته شوند:
Unit Test قادر نیست تمام باگها و اشکالات موجود در برنامه را تشخیص دهد و نباید بهعنوان تنها روش تست نرمافزار در نظر گرفته شود.
چون Unit Testing فقط روی بخشهای کوچک برنامه تمرکز دارد، برای تست کامل سیستم کافی نیست و باید در کنار روشهایی مثل Integration Testing یا End-to-End Testing استفاده شود.
آموزش Unit Testing با یک مثال عملی
قبل از مثال این را در ذهن داشته باش: Unit Testing یعنی:
قبل از اینکه کل برنامه را اجرا کنیم، یک تکه خیلی کوچک از کد را با ورودی مشخص اجرا کنیم و چک کنیم خروجیاش دقیقاً همانی هست که انتظار داریم یا نه.
صورت مسئله: فرض کنید تابعی داریم که سن یک فرد را دریافت میکند و مشخص میکند که او بزرگسال است یا کودک.
یک عدد میگیرد
اگر عدد بزرگتر از 18 باشد، میگوید "Adult"
اگر 18 یا کمتر باشد، میگوید "Child"
این فقط یک تکه کوچک از برنامه است --> یعنی یک Unit.
checkAge(age)
در Unit Testing، این تابع را بهصورت مستقل بررسی میکنیم. ابتدا یک مقدار مشخص (مثلاً ۲۰) به تابع میدهیم و انتظار داریم خروجی "Adult" باشد. اگر خروجی دقیقاً همان مقدار مورد انتظار باشد، تست با موفقیت انجام شده است.
تست اول:
ورودی: 20
checkAge(20) --> باید "Adult" بدهد
○ اگر تابع "Adult" برگرداند --> تست پاس شده ○ اگر چیز دیگری برگرداند --> تست Fail شده
در قدم بعد، مقدار دیگری (مثلاً ۱۰) را به تابع میدهیم و انتظار داریم خروجی "Child" باشد. با موفقیت این تست، مطمئن میشویم که تابع در حالتهای مختلف، رفتار درستی دارد.
تست دوم
ورودی: 10
checkAge(10) --> باید "Child" بدهد
○ اگر خروجی "Child" باشد --> تست پاس ○ اگر نباشد --> تست Fail
این دقیقاً مفهوم Unit Testing بود.
کاری که کردیم:
یک واحد کوچک از کد را جدا کردیم
به آن ورودی مشخص دادیم
گفتیم چه خروجیای انتظار داریم
نتیجه را با انتظارمان مقایسه کردیم
این تستها قبل از اجرای کل برنامه انجام میشوند و به ما کمک میکنند مطمئن شویم هر بخش کوچک از کد بهدرستی کار میکند. به همین دلیل، Unit Testing باعث کاهش باگها و افزایش اطمینان در توسعه نرمافزار میشود.
نتیجه گیری
در این مطلب با هم بررسی کردیم که Unit Testing چیست و چه کاربردی دارد. زمانی که تصمیم میگیرید یک برنامه نویس حرفه ای شوید، باید بسیاری از تکنولوژیهای مختلف را شناخته و بتوانید از آنها در پروژه خود استفاده کنید. Unit Test سطح اول آزمایش نرم افزار بوده که توسط توسعه دهندگان پروژه یا مهندسان کنترل کیفیت انجام میشود. اگر این تست درست انجام شود در مراحل بعدی توسعه محصول کار تست نرم افزار بسیار آسان میشود. به عنوان یک برنامه نویس حرفه ای بهتر است با روش تست نرم افزار کار بکنید. اگر تجربه کار با Unit Testing یا نظری درباره آن دارید، خوشحال میشویم با ما و کاربران سون لرن به اشتراک بگذارید.