Unit Testing مقدماتی
Unit Testing مقدماتی
بخشی از آموزش جامع C# و .NET 10
محتوای درس Unit Testing مقدماتی
Unit Test رفتار یک واحد کوچک از کد را بهصورت خودکار بررسی میکند و امکان Refactoring امنتر و تشخیص Regression را فراهم میسازد. تست خوب سریع، مستقل و قابل تکرار است.
۱. Arrange, Act, Assert
در الگوی AAA ابتدا داده و وابستگیها آماده، سپس رفتار اجرا و در پایان نتیجه بررسی میشود.
مثال
static int Add(int a,int b)=>a+b;
int actual=Add(2,3);
Console.WriteLine(actual==5);در این مثال، مفهوم «Arrange, Act, Assert» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۲. xUnit
xUnit یکی از Frameworkهای رایج تست در .NET است و Fact و Theory را برای تست ثابت و پارامتری ارائه میکند.
مثال
// [Fact]
// public void Add_Returns5() => Assert.Equal(5, Add(2,3));در این مثال، مفهوم «xUnit» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۳. تست رفتار
بهتر است تست روی رفتار عمومی متمرکز باشد نه جزئیات داخلی Implementation.
مثال
static bool IsAdult(int age)=>age>=18;
Console.WriteLine(IsAdult(18));در این مثال، مفهوم «تست رفتار» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۴. Theory و InlineData
برای چند ورودی مشابه میتوان از Theory و داده پارامتری استفاده کرد.
مثال
// [Theory]
// [InlineData(18,true)]
// [InlineData(17,false)]در این مثال، مفهوم «Theory و InlineData» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۵. نامگذاری تست
نام تست باید شرایط، رفتار و انتظار را تا حد امکان روشن کند.
مثال
// Method_Scenario_ExpectedResult
// Withdraw_InsufficientBalance_Throwsدر این مثال، مفهوم «نامگذاری تست» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۶. مثالهای عملی
public class PriceCalculatorTests
{
[Fact]
public void ApplyDiscount_ReturnsDiscountedPrice()
{
decimal result = PriceCalculator.ApplyDiscount(100m, 10m);
Assert.Equal(90m, result);
}
}این نمونه عملی چند مفهوم فصل را در کنار هم قرار میدهد و برای مشاهده رفتار واقعی کد قابل اجرا و تغییر است.
[Theory]
[InlineData(100, 10, 90)]
[InlineData(200, 25, 150)]
public void ApplyDiscount_Works(decimal price, decimal rate, decimal expected)
{
Assert.Equal(expected, PriceCalculator.ApplyDiscount(price, rate));
}این نمونه عملی چند مفهوم فصل را در کنار هم قرار میدهد و برای مشاهده رفتار واقعی کد قابل اجرا و تغییر است.
۷. خطاهای رایج
• تست چند رفتار مستقل در یک Test
• وابستگی Unit Test به فایل، شبکه یا زمان واقعی بدون کنترل
• تست مستقیم Private Method بهجای رفتار عمومی
۸. نکات اجرایی
• نامها، Typeها و Methodها را متناسب با مفهوم دامنه و بدون ابهام انتخاب کنید.
• هشدارهای کامپایلر و Nullable را بدون بررسی خاموش نکنید.
• منطق هر بخش را تا حد امکان کوچک، قابل تست و مستقل از I/O غیرضروری نگه دارید.
۹. تمرین عملی
برای کلاس BankAccount تستهای Deposit، Withdraw، جلوگیری از مبلغ منفی و کسری موجودی بنویسید.
۱۰. جمعبندی
در این فصل، مبانی «Unit Testing مقدماتی» با تمرکز بر ساختارهای اصلی زبان، الگوهای صحیح استفاده و خطاهای رایج بررسی شد. تسلط بر این مفاهیم زمینه لازم برای اتصال موضوع به فصلهای بعدی و طراحی کدهای خواناتر، قابل نگهداری و قابل تست را فراهم میکند.