تست واحد (UnitTest) یک روش برای تست کردن کدهای نرمافزار است که در آن، بخشهای کوچک و جداگانه کد به صورت خودکار تست میشوند. در این روش هدف اصلی اطمینان از صحت و عملکرد صحیح هر بخش از کد و تاثیر نگذاشتن، تغییرات اعمال شده در یک بخش از کد بر سایر بخشها است.
در این روش هر بخش از کد مستقل و جداگانه عمل میکند و به صورت خودکار تست میشود. این تستها به صورت خودکار و با کمک ابزارهای خاصی انجام میشوند و نیاز به دخالت انسانی ندارند. در صورتی که نتیجه تست کد مثبت باشد، یعنی آن بخش مشخص از کد به درستی عمل میکند و مشکلی در آن وجود ندارد. در صورتی که نتیجه تست منفی شود، یعنی در آن بخش از کد خطا و باگ وجود دارد و باید برطرف شود.
مزیت اصلی این روش، افزایش سرعت و کاهش هزینههای تستکردن کدها است. به علاوه، با استفاده از این روش، میتوان اطمینان حاصل کرد که تغییرات اعمال شده در کد، روی نیازمندیهای کاربر تاثیر نگذاشته است و روی کارکرد نرمافزار تاثیری ندارد.
یک تست واحد (UnitTest) خوب چه ویژگیهای دارد؟
نوشتن تستهای واحد (UnitTest) خوب بخشی ضروری از فرایند توسعه نرمافزار است. تستهای واحد کمک میکنند تا مطمئن شویم، کد نوشته شده (توسعه داده شده) همانطور که تیم بیزنس یا تحلیل انتظار دارند، کار میکند و تغییرات احتمالی در آینده (بر اساس نیازهای جدید) در کد شما عواقب ناخواستهای ایجاد نمیکند. در این مقاله کوتاه، ما در مورد بعضی از نکات مهم برای نوشتن تستهای واحد صحبت خواهیم کرد. به بیان دیگر برای این کار معیارهایی تعریف میکنیم که در نهایت میتوان این معیارها را با تستهای از قبل نوشته شده تطبیق داد.
در صورتی که این معیارها با تستهای نوشته شده شما تطابق داشته باشند، میتوان گفت شما راه را درست رفتهاید و زمانی که برای نوشتن تست صرف کردهاید، هدر نرفته است. این جمله را دوباره بخوانید «هدر نرفته است!» این جمله یعنی اگر برای نوشتن تست مسیر اشتباهی را دنبال و یا از الگوهای غلط پیروی کرده باشید، عملا تستهایی که نوشتهاید و یا از قبل ایجاد کردهاید، هیچ کمکی به شما نخواهند کرد. آنها صرفا تکه کدهایی هستند تا نهایتا code coverage شما رو بالا میبرند!
ویژگیهای کلیدی نوشتن تست واحد (UnitTest) خوب
حالا که با اهمیت نوشتن درست تست نرمافزار آشنا شدیم، با هم ویژگیهای کلیدی نوشتن یک تست خوب را بررسی خواهیم کرد.
۱- از الگوی KISS یا Keep it simple در نوشتن تستها استفاده کنید
یک UnitTest خوب ساده نوشته میشود و برای همه قابل فهم است. به بیان دیگر سعی می شود کمترین پیچیدگی در کدها را داشته باشیم چرا که بعد از اعمال تغییرات در توسعه مجبور هستیم، تستهای نوشته شده را بازنگری (Refactor) کنیم. در زمان بازنگری خیلی مهم است که متوجه روند انجام و نتیجه تست شویم تا بتوانیم تست را بر اساس نیازهای جدید تطبیق دهیم.
۲- مشخصا یک قسمت از کد را تست کنید
یک تست خوب باید تنها و تنها یک قسمت مشخص را تست کند و جواب مورد انتظار ما بعد از اجرای تست نمایانگر Pass/Fail شدن تست خواهد بود.
۳- تمام ورودیها را تست کنید
اگر روشی دارید که به ازای دریافت ورودی، خروجی مشخصی را برمیگردانند حتما تمام ورودیهای ممکن را بررسی کنید در بعضی مواقع برنامهنویسها صرفا ورودیهایی که باعث pass شدن تست میشوند را بررسی میکنند و از ورودیهایی که باعث fail شدن تست میشوند، اجتناب میکنند.
پیشنهاد مطالعه: تست اکتشافی چیست؟
۴- وابستگیها را Mock کنید
یک UnitTest به هیچ سرویسی وابسته نیست و عملکرد همه سرویسهای خارجی مثل وبسرویسها، صفها، دیتابیس و … باید Mock شوند و باید با توجه به نیاز تست و آن چیزی که تست باید بررسی کند و خروجی از قبل تعیین شدهای را برگردانند. تستهای واحد جزئیات پیادهسازی را تست نمیکنند که این یکی از کلیدیترین مباحث در تستهای واحد است. هر تست صرفا یک واحد مشخص را بررسی و تست میکند.
۵- یک تست خوب رفتار کد را تست میکند
بعضی اوقات برنامهنویسان تنها برای بالا بردن Code-Coverage در پروژه تست مینویسند و به رفتار کدها یا validation ها اهمیتی نمیدهند. در این حالت در صورتی که رفتار با Refactor کردن کدهای قدیمی و یا تغییر نیاز سمت کسب و کار تغییر کند، تست نوشته شده Fail نخواهد شد و این باعث مشکلات زیادی میشود.
۶- تستها باید به صورت مستقل اجرا شوند
اجرای تستها نباید به هم وابسته باشند. به بیان دیگر نباید یک ترتیب اجرا داشته باشیم. برای مثال اگر دو تست با عنوانهای A و B داشته باشیم، هر دو تست باید بدون اولویت اجرا شوند. اگر بین دو یا چند تست اولویتی در اجرا وجود دارد، قطعا این مسیر را اشتباه است. نباید هیچ وابستگی چه از نظر سرویس و چه از نظر دیتا وجود داشته باشد. هر تست باید تمام نیازهای خود را در بدنه خودش فراهم کند و نباید منتظر بماند تا یک تست اجرا شود و از خروجی تست اجرا شده، برای رفع کردن نیاز خود استفاده کند.
۷- تستها قابلیت چندبار اجرایی شدن را دارند
در صورتی که تست نوشته شده شما تنها یک بار اجرا میشود و یا اجرا آن مدت زمان زیادی طول میکشد، لازم است در آن بازنگری کنید. چرا که تستهای واحد به سرعت در اجرا معروف هستند. قطعا وجود یک وابستگی باعث این کندی می شود که میتواند شمال وابستگی به دیتابیس و …باشد. مطمئن شوید که همه وابستگیها را Mock کرده باشید.
۸- از اصول نامگذاری تستها استفاده کنید
استفاده از اصول نامگذاری تستها خیلی مهم است زیرا باعث میشود، خواننده تست شما، با نگاه کردن به عنوان تست متوجه شود که شما چه چیزی، در چه شرایطی و با چه خروجی تست میکنید. در ادامه و برای مثال به یک روش نامگذاری متداول تست میپردازیم:
نامگذاری A-A-A
این روش نامگذاری سعی میکند تا حدود زیادی خواننده را نسبت به تست نوشته شده، آگاه کند.
مثال زیر یک نمونه از این نوع نامگذاری است:
AddNewCustomer_NameIsNull ThrowInvalidArgumantExcpetion
در این مثال بخش اول رفتاری است که تست مورد نظر بررسی میکند. مانند اضافه شدن یک مشتری جدید، که اسم مشتری در این جا null در نظر گرفته شده است. در این حالت انتظار داریم ThrowInvalidArgumantExcpetion انجام شود.
۹- تا جای ممکن از TDD بهره ببرید
به جای این که نرمافزار یا ماژول مورد نظر را توسعه دهید و بعد تستها را بر اساس کدهای نوشته شده بنویسید، به داستان از آخر به اول نگاه کنید! شما میدانید که یک کلاس تعریف شده دارید که وظیفه مشخصی را انجام میدهد و انتظار دارید که خروجی مشخصی را هم برگرداند. این تمام چیزی هست که برای نوشتن تست نیاز دارید، در این روش استفاده از ابزارهای Mocking میتواند کمک فراوانی کند.
پیشنهاد مطالعه: تفاوت تضمین کیفیت و کنترل کیفیت
در صورتی که اول تست را بنویسید در زمان توسعه با دید بازتری به مسائل کسب و کاری فکر میکنید و پیادهسازی شما کاملا بر اساس این نیاز خواهد بود. ممکن است در این روش برای نوشتن تست چالشهای جدیدی را تجربه کنید و زمان زیادی را برای این موضوع صرف کنید اما در عین حال میتوانید مطمئن شوید که نیاز واقعی را شناختهاید و کدهای توسعه داده شده کاملا با نیاز کسب و کار همخوانی دارد.
۱۰- در سریعترین زمان ممکن تستها را بنویسید
در بعضی مواقع نوشتن تستها یک اختیار و نه یک الزام در نظر گرفته میشود. این موضوع به شکلهای مختلف در سازمانها نمایان میشود. به طور مثال تستها به عنوان یک بدهی فنی در نظر گرفته میشوند. یعنی نوشتن تستها به زمان دیگری موکول میشود، به طوری که از زمان توسعه نرمافزار تا زمان نوشتن تست زمان زیادی میگذرد. این موضوع نباید اتفاق بیافتد و تستها باید در سریعترین زمان ممکن نوشته شوند.
جمعبندی
در نتیجه، شما با پیروی از این شیوهها، میتوانید تست واحد (UnitTest) ساده، خاص، جامع و مستقل ایجاد کنید. به یاد داشته باشید، هدف از تست واحد این است که مطمئن شوید، کد شما همانطور که انتظار می رود، کار میکند. بنابراین برای نوشتن تستهای واحد خوب زمان بگذارید.
دیدگاهتان را بنویسید