به تصویر بالا نگاه کنید فکر می کنید کلاس دیاگرام بالا متلعق به کدام قسمت از یک نرم افزار است. شاید حدس زدن آن در اولین مرحله برای خیلی ها مشکل باشد پس لطفا بر روی تصویر کلیک کنید تا تصویر را با اندازه واقعی مشاهده کنید و از نام متدها قضیه را حدس بزنید. تمام کلاس های بالا برای تست متدهای کلاس های نرم افزار یا همان تست واحد (Unit Test) طراحی و پیاده سازی شده است. شاید اگر به سورس بسیاری از نرم افزارهای مشهور دسترسی داشته باشید، حتما مشابه این کلاس ها را در یک پکیچ جداگانه در سورس خواهید یافت (تصویر بالا مربوط به مولفه منوی RadControls از شرکت Telerik است که حنما اکثر توسعه دهندگان وب با محصولات این شرکت آشنا هستند). پس اجازه بدهید در پایین به بررسی اصول و نحوه پیاده سازی تست های واحد بپردازیم.
تست واحد (Unit Testing):
یک واحد کوچکترین قسمت قابل تست یک نرم افزار می باشد. که این واحد در برنامه نویسی شی گرا می تواند یک متد باشد و در برنامه نویسی رویه ای می تواند کل برنامه (در زبانی مانند کوبول) یا یک تابع و … باشد. در تست واحد، هر واحد به طور جداگانه تست می شود به این صورتیکه تکه کدی نوشته می شود، تا آن واحد را فراخوانی کند و به کار ببرد تا صحت یا عدم صحت عملکرد آن را بررسی کند (ما کدی را می نویسیم گه کد اصلی برنامه را تست می کند).
هدف و فلسفه تست واحد ما از تست واحد استفاده می کنیم تا نشان دهیم که واحد مورد نظر کاری را که ما فکر می کنم انجام می دهد یا نه. |
چرا باید تست واحد را انجام بدهیم؟
در دروسی مانند آزمایشگاه مدار منطقی، معماری کامپیوتر و … برای اینکه یک مدار را پیاده سازی کنید چگونه عمل می کردید. ابتدا تک تک IC های را که باید بکار میبردید تک به تک تست می کردید تا از صحت عملکرد هر کدام مطمئن شوید تا مجبور نباشید بعد از صرف ساعت ها وقت دنبال مشکل بگردید و در آخر متوجه شوید که IC مشکل داشت. اولین دلیل تست واحد نیز همین می باشد که ما بعد از اضافه کردن یک واحد به نرم افزار می خواهیم از صحت عملکرد آن مطمئن شویم. دومین دلیل کاهش زمان و هزینه ای است که باید صرف اشکال زدایی شود، در تست واحد شما می دانید کجا را باید برای کشف دلیل خطا و رفع آن جستجو کنید یعنی در این مرحله دامنه بررسی فقط به همان واحد محدود می شود. دلیل سوم در تست واحد می توان چندین تست را در یک زمان اجراء کرد.
مزایا و منافع
علاوه بر دلایلی که در بالا اشاره شد، ما با انجام تست های واحد منافع زیادی را به دست می آوریم که به بعضی از آنها در ادامه اشاره خواهد شد.
1- تست های واحد همانند یک سند اجرایی هستند که نشان می دهند شما انتظار دارید که کد نوشته شده در شرایط مختلف چگونه عمل کند. اعضای تیم می توانند برای درک عملکرد کد و اینکه چگونه آن را بکار ببرند به تست های واحد مراجعه کنند.
تست های واحد مستنداتی هستند که با تغییر و اصلاح کد بروز رسانی می شوند.
علاوه بر اینها نظرات و حدس های برنامه نویس را در تست ها می توانیم مستند سازی کنیم.
2- به اشتراک گذاری کد با دیگران راحتتر است، چون اگر عضوی از تیم کد را طوری دستکاری کنید که درست کار نکند، اجرای تست ها با شکست روبرو می شود.
3- با انجام تست های واحد، زمان انجام تست ها در سایر فازها کاهش می یابد.
4- تست ها، انتظارات برنامه نویس را در مورد چگونگی عمل کردن یک قطعه کد، ارزیابی می کنند.
بهانه و مقاومت
تغییر همیشه وجود دارد، رویه ها، قوانین و روش های جدید بوجود می آیند و ایجاد می شوند ولی هر پدیده جدیدی همیشه با مقاومت بعضی از افراد در اجراء روبرو می شود. اگر شما از تست های واحد استفاده نمی کردید احتمالا سوالات یا بهانه های مانند عناوین زیر را مطرح کنید:
1- نوشتن تست ها احتیاج به زمان زیادی دارد: این جمله ای که توسط افرادی زیادی گفته می شود ولی آیا اینگونه است. تصور کنید که شما یک باغچه دارید که مسئولیت رسیدگی آن بر عهده شما است، آخر هفته به باغچه نگاه می کنید مشاهده می کنید که چمن ها بزرگتر شده اند و گل ها نیز نیاز به رسیدگی دارند ولی تا هفته بعد صبر می کنید و هفته بعد دوباره صبر، اما بعد از چند هفته مشاهده می کنید که چمن ها خیلی بزرگ شده اند، علف های هرز کل محیط را احاطه کرده اند، گل ها پژمرده شده اند و …. در هفته اول شما می توانستید با یک قیچی باغبانی و در چند دقیقه کل کار را انجام دهید ولی حالا شاید با ساعت ها کارها و تجهیزات اضافی بتوانید کارتان را انجام بدهید البته شاید. تست های قطعه نیز مانند انجام دادن کارهای باغبانی در آخر هفته است، یعنی با تست قطعه ما می توانیم فرآیند تست را ارزان تر و و با کیفیت بالا انجام دهیم و ریسک نیاز به زمان زیادی برای تست را در آخر پروژه حذف کنیم.
2- اجرای تست های نیاز به زمان زیادی دارید: یک آگاهی بازرگانی بود که احتمالا از تلویزیون خودمان آنرا مشاهده کرده اید، خانمی که باید غذا را آماده می کرد، به خرید می رود و … خانم غذا را آماده می کرد آنرا تو آرام پز قرار می داد و دیگر تمام شد تا شب می توانست به کارهای دیگرش برسد. برای تست های که نیاز به زمانی زیادی برای اجرا دارند ما نیز همین کارها را انجام می دهیم. یعنی زمانی که باید کار دیگری را انجام دهم تست را اجراء می کنم چون اجرای تست فرآیندی خود کار است و به بقیه کارها می رسیم. یا در زمانهای بی کاری و یا آخر هفته. تست های را که نیاز به زمان زیادی دارند باید دسته بندی کرد و آنها را جدا از تست های دیگر و در دفعات کم اجرا کرد.
3- تست کردن شغل من نیست: خوب این کار شما نیست. پس تصور کنید که دو توسعه دهنده داریم نفر اول تست ها واحد را انجام می دهد و دیگری نه. بعد از اتمام کار، کدهای نوشته شده به تیم تست و کنترل کیفیت ارجاع داده می شوند. نتیجه تقریبا روشن است کدهای نفر اول با حداقل خطا برای رفع اشکال ارجاع داده می شود ولی نفر دوم باید لیست درازی از خطاها را اصلاح کند. کدام یک از اینها مسیر ترقی را سریع طی خواهد کرد و از امنیت شغلی برخودار خواهد بود حتما نفر اول.
4- اگر من تست ها را انجام دهم احتمالا افراد دیگری که مسئول تست هستند احتمالا کارشان را از دست بدهند: شما اصلا نگران این موضوع نباشید شما فقط مسئول تست واحدها هستید، و این فقط مرحله بسیار کوچک از فرآیند کلی تست می باشد.
5- چرا از تست کردن به صورت دستی، استفاده نکنیم؟ تست دستی امکان نفوذ خطاهای انسانی به سیستم را افزایش می دهد و همچنین تکرار کردن تست های دستی، بسیار مشکل تر است. برای اینکه تست های دستی را دوباره انجام بدهیم، به مستنداتی نیاز داریم که مراحل انجام تست ها را شرح بدهند. با تغییر کد، این مستندات به سرعت کهنه می شوند و این یعنی اینکه برای به روزنگهداشتن مستندات، باید کار اضافی انجام دهیم.
در مراحل اول بیماری تشیخص بسیار سخت ولی درمان خیلی آسان است. اما بعد از پیشرفت بیماری تشخیص آسان و درمان بسیار سخت می باشد. این جمله را برای تست واحد باز نویسی کنید. |
(در قسمت بعدی به نحوه پیاده سازی تست های واحد و معرفی Nunit خواهیم پرداخت.)