شهریور
۲
۱۳۹۷

مقدمه ای بر unit testing با استفاده از googletest

با سلام

قبل از هر چیز باید بگم از اینکه بعد از مدتها تونستم تو این چند روز چند پست در وبسایت بذارم خیلی خوشحالم و امیدوارم که مفید بوده باشن.

چیزی که امروز به ذهنم رسید دربارش صحبت کنم مبحث تست واحد یا همان unit testing در هنگام کدنویسی است.

باید اعتراف کنم که خودم هم تا الان در یک برنامه واقعی از ابزارهای یونیت تست استفاده نکردم و ندیدم که کسی یا شرکتی هم از این موضوع استفاده کنه.

دلیل این مطلب هم عجله ای است که همیشه کارفرماها و مدیران ارشد برای دریافت سریع نتیجه دارن. یعنی اکثرا ترجیح میدن برنامه با باگ سریعتر اجرایی بشه و بعد از اون ماه ها و شاید سالها درگیر رفع ایرادها باشن تا اینکه به صورت اصولی مراحل طراحی و پیاده سازی و تست را پشت سر بذارن و در نهایت مدتها با یک نرم افزار با کیفیت مشتری ها را راضی کنند.

متاسفانه این فرهنگ غلطی است که علتش هم به نظرم عدم شناخت واقعی و ارزش گذاشتن برای یک محصول نرم افزاری است. لااقل من در اکثر جاهایی که دیدم و شنیدم اینطور بوده. اگر دقیقتر نگاه کنیم حتی در مهندسی های دیگه مثل صنعت خودرو هم همین وضع را داریم. بگذریم حسابی زدم جاده خاکی 🙂 برسیم به بحث اصلیمون که همون بحث unit test است.

برای استفاده از این تکنیک ابزارها و لایبرری های متعددی وجود داره. لیست ابزارهای unit testing در زبان های مختلف را میتوانید در این لینک ببینید.

یکی از این ابزارها برای زبان برنامه نویس C++ فریم ورک نرم افزاری شرکت گوگل به نام googletest است.

برای دانلود این ابزار میتوانید وارد صفحه اصلی این پروژه در سایت گیت هاب شوید و پکیج zip شده این نرم افزار را دانلود کنید.

برای استفاده از گوگل تست ابتدا باید اون رو بر روی سیستم خودتون build کنید تا خروجی libgtest.a یا مشابه آن در سیستم شما ساخته بشه.

اگر ابزار  cmake را بر روی سیستم نصب شده دارید داخل پوشه دانلود شده برید سپس دستورات زیر را اجرا کنید:

 

اگر cmake بر روی سیستم شما نصب نیست میتوانید با استفاده از دستور زیر این لایبرری را بیلد کنید:

 

اگر هم از کامپایلر مایکروسافت استفاده میکنید وارد پوشه msvc بشوید و از طریق فایل sln موجود در این شاخه کتابخانه گوگل تست را بر روی سیستم ویندوزیتون بیلد کنید. (من شخصا این مورد رو تست نکردم)

اگر این مرحله را به درستی طی کنید فایل libgtest در سیستم شما ایجاد میشود.

بعد از این مرحله وارد قسمت اصلی انجام روال یونیت تست میشویم. برای اینکه با این روال و امکانات گوگل تست آشنا بشیم چند فایل سورس نمونه به همراه یونیت تست های ساخته شده برای آنها در پوشه Samples از پکیجی که دانلود کردیم قرار داده شده اند.

فایل های مشابه sample۱.cc مشابه سورس اصلی برنامه ما هستند که قراره فرایند یونیت تست بر روی متدهای آن اجرا بشه. فایل های مشابه sample۱_unittest  هم شامل یونیت تست های نوشته شده توسط ما برای تست اجزا برنامه هستند.

فرض کنید در برنامه متدی برای محاسبه فاکتوریل به صورت زیر نوشتیم:

حال تصمیم داریم این متد را در شرایط گوناگون تست کنیم برای اینکار اولین یونیت تست رو به صورت زیر در فایل سورس دیگری پیاده سازی میکنیم:

عبارت TEST در ابتدای هر بلاک آغاز کننده یک بلاک یونیت تست است. پارامتر اول TEST اسم متدی از برنامه است که قرار است تست شود. عبارت دوم نامی برای این یونیت تست است که بعدا در دیدن نتایج به ما کمک میکند.

EXPECT_EQ درستی دو آرگومان داخلی را تست میکند. در اینجا اگر نتیجه فاکتوریل ۰ مقدار ۱ باشد یونیت تست موفق خواهد بود. در واقع ما انتظار خودمان را از نتیجه ای که باید متد فاکتوریل برگرداند با نوشتن این عبارت تست کردیم.

EXPECT_EQ فقط یکی از عبارت هایی است که میتوانیم استفاده کنیم. لیست کاملی از دستورات در این لینک آمده که میتوانید دانلود کنید.

به طور مثال میتوانید بزرگتر و کوچکتر بودن مورد انتظارتان را نیز بیان کنید. همچنین در صورت استفاده از ASSERT_EQ به جای عبارت بالا در صورت fail شدن تست نتیجه کار ادامه پیدا نمیکند و فرایند تست به پایان میرسد و عبارت ها و کارهای بسیار بیشتر دیگر که در صورت تمایل میتوانید خودتان بررسی کنید.

تعداد عبارت ها هم در اختیار ماست. مثلا برای یک متد میتوان n یونیت تست نوشت که شرایط مختلفی را تست کنند. همچنین تعداد عبارت هایی که هر یونیت تست تست میکند نامحدود است.

به این ترتیب میبینید که کاملا میتوانیم اجزا برنامه را به خوبی تست کنیم. نتیجه نمایش داده شده علاوه بر درستی و غلطی زمان صرف شده در متد شما را نیز اعلام میکند که در صورت غیر بهینه بودن میتوانید آن را اصلاح کنید.

بعد از نوشتن یونیت تست ها نوبت به کامپایل و اجرای یونیت تست میرسه. برای اینکار ابتدا سورس برنامه خودمان را کامپایل میکنیم:

در اینجا به طور مثال سورس sample1 که در پوشه samples قراردارد را کامپایل کردیم.

سپس با استفاده از عبارت زیر سورس sample1_unittest را نیز کامپایل میکنیم:

در صورتیکه مشکلی نداشته باشید فایل اجرایی my_test برای شما ساخته میشود. با اجرای این فایل نتیجه ای مشابه زیر خواهید گرفت:

همانطور که ملاحظه میکنید نتیجه کلی تست ها در اینجا نشان داده شده. نتیجه هر تست کنار آن اعلام شده و در آخر هم عبارت PASSED موفقیت آمیز بودن تمام تست ها را اعلام کرده است.

اگر نتیجه ای مطابق انتظار ما نباشد به جای عبارت ok عبارت failed با رنگ قرمز به همراه توضیحات مربوط به اشکال به وجود آمده نشان داده خواهد شد. که خودتان میتوانید تست کنید.

 

به این ترتیب میتوانیم برای کدهایی که نوشتیم یونیت تست تهیه کنیم و بعد از کدنویسی و مخصوصا قبل از هر ریلیز برنامه از عدم وجود اشکال در اجزا برنامه خودمان اطمینان پیدا کنیم.

خیلی وقت ها پیش میاد که در حین توسعه برنامه سهوا یک کدی را دستکاری میکنیم و به خیال اینکه کارمان درست بوده از تست اون قسمت صرفنظر میکنیم و  برنامه با اشکال بیرون میره. در صورتیکه روال های یونیت تست داشته باشیم و مثلا به صورت یک اسکریپت قبل از هر ریلیز تمام روال ها را بتونیم تست بگیریم از وقوع همچنین مواردی هم جلوگیری خواهیم کرد.

امیدوارم این مطلب مورد توجه دوستان خوبم قرار گرفته باشه.

به امید دیدار مجدد.

اشتراک گذاری این مطلب:

نوشته‌های مرتبط

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

برنامه‌نویس ++‏C/C‏ - برنامه‌نویس سیستم‌های گرافیکی با استفاده از کتابخانه ‏OpenGL - برنامه‌نویس #‏C و ..‏



فرستادن دیدگاه