آموزش Unit Testing با استفاده از NUnit و Moq بخش اول: آشنایی با NUnit



در این سری آموزش قصد داریم به فریم ورک محبوب NUnit و همچنین Mocking بوسیله کتابخانه محبوب Moq بپردازیم.




در این مقاله از GitHub Gist استفاده شده است و لود شدن بخش مربوط به کد ها ممکن است کمی زمانبر باشد. همچنین ممکن است نیازمند نرم افزار رفع تحریم باشید.


تعریف Unit Test

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


مفهوم Red-Green-Refactor

این مفهوم در Test Driven Development برای اولین بار بیان شد. در تکنیک Red Green Refactor رویه زیر را پیشنهاد میکند

  • تست بنویسید
  • تست را اجرا کنید و ببینید که تست نتیجه اشتباه را بر میگرداند و fail میشود
  • کد اصلی را بنویسید
  • تست را دوباره اجرا کنید
  • در صورتی که تست pass شد(نتیجه آن سبز شد) کد را refactor کنید

آشنایی با NUnit

یک فریم ورک open source مخصوص Unit Testing در دات نت می باشد که کار Unit Testing را بسیار آسان می کند. به وسیله NUnit میتوانیم یک پروژه مخصوص Unit Testing داشته باشیم و تست ها را به راحتی مانیتور کنیم. در تاریخ نوشتن این مقاله طبق آمار NugetTrends.com پکیج مربوط به NUnit بیش 117 میلیون بار دانلود و نصب شده است.

آمار دانلود پکیج NUnit
آمار دانلود پکیج NUnit


ایجاد پروژه نمونه

پس از کلیک بر روی Create New Project به سراغ ساخت یک Class Library می رویم و سپس یک نام برای آن انتخاب میکنیم.

سپس به سراغ نصب پکیج NUnit می رویم. میتوانیم از قسمت Package Manager Console و با دستور زیر پکیج NUnit را نصب کنیم.

Install-Package NUnit -Version 3.13.2

و یا میتوانیم بر از طریق Manage Nuget Package به سراغ پکیج NUnit رفته و آن را نصب کنیم

پس از نصب NUnit آیکون مربوط به Class Library تغییر میکند که نشان میدهد که این پروژه به تست تغییر کاربری داده است.


ایجاد اولین تست

ابتدا یک کلاس ایجاد میکنیم و آن را با صفت TextFixture علامت گذاری میکنیم. سپس یک متد ایجاد کرده و آن را با صفت Test علامت گذاری میکنیم. در اینجا System Under Test و یا به صورت اختصار SUT را یک عملیات ساده در نظر میگیریم

https://gist.github.com/babaktaremi/d28c019d04af7ea0fdebed0a508cabf9

از قسمت search به دنبال Test Explorer می گردیم.


محیط Test Explorer به شکل زیر باز میشود.

بر روی گزینه Run کلیک میکنیم و مشاهده میکنیم که تست ها Pass می شوند.

آشنایی با ReSharper

یک ابزار بسیار قدرتمند که به نوشتن کد بهتر کمک بسیاری میکند و برای هر کد Suggestion های بسیار خوبی را ارائه میدهد. ReSharper در زمینه Unit Testing نیز Test Session بسیار قدرتمندی را ارائه میدهد که تست کد را بسیار آسان میکند. برای دانلود ReSharper و نصب آن میتوانید به این لینک مراجعه کنید.
پس از نصب ReSharper یک گزینه کنار هر تست به شکل زیر نمایان می شود که بوسیله آن میتوان تست را به راحتی Run کرد.

آشنایی با Assertion در NUnit

یک Unit Test معمولا دو نتیجه را در بر دارد . یا تست Fail و Red میشود و یا تست Pass و Green میشود. به وسیله Assertion می توان نتیجه یک تست را طبق شرایط بدست آورد. در مثال قبل به وسیله Assertion نتیجه Unit Test را بدست آوردیم که 2+2=4 و تست pass شد.

آشنایی با Assertion های ساده

نتیجه Inconclusive: وقتی یک تست Inconclusive باشد نتیجه آن مشخص نیست و در نتیجه نمیتوان مشخص کرد که تست Pass شده است و یا Fail شده است. بوسیله دستور زیر میتوان نتیجه تست را Inconclusive کرد.

https://gist.github.com/babaktaremi/cc7c293573fc02aed64c6aed6ff60a7b


مشاهده میکنیم که نتیجه تست با رنگ زرد Inconclusive نشان داده شده است.

ایجاد warning: وقتی یک warning ایجاد میکنیم نتیجه تست به صورت خودکار Inconclusive میشود. به صورت زیر میتوانیم در یک تست ایجاد warning کنیم و یک message را نمایش دهیم.

https://gist.github.com/babaktaremi/6f358398e272b35574f8ba5bf1c0e642

ایجاد Equality Check: وقتی میخواهیم نتیجه دو مقدار را از نظر برابری چک کنیم میتوانیم از دستورات زیر استفاده کنیم.

https://gist.github.com/babaktaremi/d884796a5fccba05c0bc3c9fb1808735
https://gist.github.com/babaktaremi/78ce0e9ca17fb287954e1b8f14aaa83a




نکته قابل توجه این است که دستور Assert.That و Is میتواند دستورات مختلفی را چک کند مانند:

دستور Is.False: این دستور چک میکند که نتیجه یک Assert برابر False باشد.

دستور Is.Ordered : بررسی میکند که یک Collection به صورت مرتب شده باشد.

دستور Is.Unique : بررسی میکند که تمام المان های یک Collection یکتا و Unique باشد.

دستور Is.AssignableFrom: بررسی میکند که یک type از نوع type تعریف شده باشد

مابقی قسمت های مربوط به Assert.That را میتوانید در تیکه کد زیر ببینید.

https://gist.github.com/babaktaremi/df61f960eeb6d8629c8685e708da41e5

بررسی String Assertion

علاوه بر Assert معمولی، میتوانیم بوسیله String Assertion بررسی های مخصوص به String را انجام دهیم. کارهایی که میتوانیم با string Assertion انجام دهیم که پرکاربرد ترین آنها عبارتند از:

دستور AreEqualIgnoringCase: بررسی میکند که دو string باهم برابرند بدون در نظر گرفتن بزرگ و کوچک بودن کاراکتر های آنها.

دستور Contains: بررسی میکند که یک string شامل یک sub string خاص هست یا خیر.

دستور IsMatch : بررسی میکند که آیا یک string با یک regular expression برابری میکند یا خیر.

لیست کامل دستورهای string assertion را میتوانید در قطعه کد زیر ببینید.

https://gist.github.com/babaktaremi/3a6e70775f248b49d446dbcbaa2c8c4b

بررسی Collection Assertion

علاوه بر string Assertion یک سری Assertion خاص برای Collection ها وجود دارد که میتوانیم بوسیله آن بررسی های مخصوص به Collection ها را انجام دهیم که پرکاربرد ترین آنها عبارتند از:

دستور AreEqual : بررسی میکند که آیا دو کالکشن دارای المان هایی با تعداد یکسان و ترتیب یکسان هستند.

دستور AreEquivalent: بررسی میکند که آیا دو کالکشن المان هایی یکسان دارند یا خیر.

لیست کامل دستورات Collection Assertion را میتوانید در قطعه کد زیر ببینید.

https://gist.github.com/babaktaremi/2a3d5abc4d76669007d6cb3fefd16e7b


بررسی صفت های پرکاربرد در NUnit

در NUnit میتوانیم متد ها و کلاس ها را بوسیله صفت ها علامت گذاری کنیم. برخی از این صفت ها عبارتند از:

صفت Test : یک Test Method را بویسیله این صفت علامت گذاری میکنیم. در واقع هر متدی که نشان دهنده یک تست باشد باید این صفت را داشته باشد.

صفت TestFixture : بوسیله این صفت یک کلاس که شامل چند تست می باشد را علامت گذاری میکنیم.

صفت SetUp : وقتی متدی با این صفت علامت گذاری شود قبل از هر تست اجرا میشود.

صفت OneTimeSetUp : وقتی متدی با این صفت علامت گذاری شود، یکبار و فقط یکبار قبل اجرای تمامی تست ها اجرا میشود.

صفت OneTimeTearDown : وقتی متدی با این صفت علامت گذاری شود ، پس از اجرای تمامی Test Case ها یکبار اجرا میشود.

صفت TearDown : وقتی متدی با این صفت علامت گذاری شود، پس از اتمام هر Test Case اجرا می شود.

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

https://gist.github.com/babaktaremi/396470254e4af87276e8193be7deca04

بررسی Data Driven Tests در NUnit

برای بررسی یک تست با data خاص دو روش وجود دارد.

استفاده از صفت TestCase

در NUnit و با استفاده از صفت TestCase میتوانیم یک Test Method را با داده های اختیاری تست کنیم. سناریو ساده زیر را در نظر بگیرید.

https://gist.github.com/babaktaremi/ad7201490a25f24222bfcf41f942d57b

حال این کلاس Price Calculator را میتوانیم بوسیله Test Case با مقدار های مختلف به شکل زیر تست کنیم:

https://gist.github.com/babaktaremi/e56ac9527be9608f531dcd785bc26580

همچنین میتوانیم با استفاده از پراپرتی ExpectedResult میتوانیم خروجی متد را به شکل دلخواه در بیاوریم و آن را با Expected Result مقایسه کنیم.

https://gist.github.com/babaktaremi/c7b5e5ce47fcab4aaea4e2c4543c29e0


استفاده از صفت TestCaseSource

وقتی میخواهیم یک تست را بر مبنای دیتای خارجی تست کنیم میتوانیم از TestCaseSource استفاده کنیم. این صفت نام یک پراپرتی Static که یک لیستی از TestCaseData بر میگرداند را میگیرد. فرض کنید که یک فایل csv به شکل زیر داریم و میخواهیم دیتای آن را برای یک Test Case وارد کنیم.

https://gist.github.com/babaktaremi/7c069c7e08e4f6effdbf71d5611c8ee3

یک پراپرتی Static با نام TestCases مینویسیم که دیتا را از داخل این فایل csv بخواند و آن را برگرداند

https://gist.github.com/babaktaremi/7699f364b666537fcae13ddc0c472726

حال این پراپرتی را در داخل TestCaseSource به شکل زیر استفاده میکنیم.

https://gist.github.com/babaktaremi/ee88ed9d9532e888e34d1a0249d36774


نتیجه گیری

در این مقاله با NUnit این فریم ورک قدرتمند و محبوب در زمینه Unit Testing آشنا شدیم . به طور کلی نوشتن تست به داشتن کدی قابل اطمینان کمک شایانی میکند. در قسمت بعدی با Mocking و کتابخانه Moq آشنا میشویم. خوشحال میشوم که نظرات شما را درباره این مقاله بدانم و همچنین اگر دوست داشتید میتوانید من را به یک قهوه مهمان کنید.

https://coffeebede.ir/buycoffee/bobby

مقالات بیشتر در دات نت زوم

https://t.me/DotNetZoom