xUnit چیست؟

xUnit چیست؟
فهرست مقاله [نمایش]

     

    xUnit چارچوبی برای نوشتن و اجرای تست‌های خودکار در دات‌نت است. هدف آن ساده‌کردن نوشتن تست‌های قابل اعتماد و سریع است تا بتوانیم با اطمینان تغییر کنیم، بازطراحی انجام دهیم و از شکستن ناخواسته‌ی کد جلوگیری کنیم. xUnit نسل تازه‌ای از چارچوب‌های تست خانواده‌ی xUnit به‌شمار می‌رود که با تاکید بر سادگی، خوانایی و جداسازی مناسب تست‌ها طراحی شده است.


    معرفی کوتاه و تاریخچه‌ی xUnit

    خانواده‌ی xUnit ریشه در شیوه‌های آزمون‌نویسی سبک دارد. xUnit برای دات‌نت با هدف بهبود تجربه‌ی توسعه‌دهندگان نسبت به چارچوب‌های قدیمی‌تر معرفی شد و به‌مرور به گزینه‌ی محبوب بسیاری از تیم‌ها تبدیل گردید؛ به‌ویژه برای پروژه‌های .NET 6/7/8 و ASP.NET Core.


    چرا xUnit؟ مزایا و فلسفه‌ی طراحی

    سادگی و سرعت در چرخه‌ی توسعه

    xUnit تلاش می‌کند اصطلاحات را ساده نگه دارد: تست‌ها به‌صورت متدهای عادی نوشته می‌شوند، مقداردهی اولیه‌ی سبک با سازنده‌ی کلاس انجام می‌شود و آزادسازی منابع در Dispose یا Fixtureها مدیریت می‌گردد. نتیجه، اجرای سریع و هزینه‌ی نگهداری پایین‌تر است.

    مقایسه‌ی کوتاه با MSTest و NUnit

    هر سه چارچوب توانمندند، اما xUnit به‌خاطر تزریق وابستگی ساده‌تر در سازنده‌ی کلاس تست، جداسازی بهتر وضعیت بین تست‌ها و داده‌محور بودن طبیعی (نظریه‌ها) نزد بسیاری محبوب است. اگرچه تیم‌هایی که سال‌ها با MSTest/NUnit کار کرده‌اند نیز می‌توانند با حداقل اصطکاک مهاجرت کنند.


    شروع سریع با xUnit

    ایجاد پروژه‌ی تست با خط فرمان

    برای شروع در یک راه‌حل دات‌نت، می‌توانید یک پروژه‌ی تست بسازید:

    dotnet new xunit -n MyProject.Tests
    cd MyProject.Tests
    dotnet test

    این دستورات یک پروژه‌ی تست می‌سازند و تست‌های نمونه را اجرا می‌کنند.

    ساختار پوشه‌ها و نام‌گذاری تست‌ها

    پوشه‌ی MyProject.Tests را مطابق لایه‌ها/ویژگی‌ها تقسیم کنید (مثلاً Services, Controllers).

    الگوی نام‌گذاری پیشنهادی کلاس تست: ClassName_Should_Behavior.

    الگوی نام‌گذاری متد تست: MethodName_Scenario_ExpectedResult.


    مفاهیم پایه در xUnit

    تفاوت [Fact] و [Theory]

    [Fact]: برای سناریوهایی که داده‌ی ورودی خاص ندارند یا فقط یک حالت را می‌سنجند.

    [Theory]: برای تست‌های داده‌محور؛ می‌توانید با ورودی‌های مختلف همان منطق را بیازمایید.

    تأمین داده‌ی تست با InlineData، MemberData، ClassData

    public class CalculatorTests
    {
        [Theory]
        [InlineData(2, 2, 4)]
        [InlineData(5, 3, 8)]
        public void Add_Should_Return_Sum(int a, int b, int expected)
        {
            var calc = new Calculator();
            var result = calc.Add(a, b);
            Assert.Equal(expected, result);
        }
    }

    برای داده‌های پیچیده‌تر از MemberData/ClassData استفاده کنید تا خوانایی حفظ شود.

    آشنایی با Assertها (مقایسه، استثناء، مجموعه‌ها)

    برابری: Assert.Equal, Assert.NotEqual

    مقداردهی: Assert.True, Assert.False, Assert.Null

    استثناء: Assert.Throws<TException>

    مجموعه‌ها: Assert.Contains, Assert.All, Assert.Collection


    سازمان‌دهی و مدیریت وضعیت (Fixture)

    الگوی IClassFixture<T>

    وقتی چند تست به یک منبع مشترک نیاز دارند (مثلاً یک سرویس با پیکربندی زمان‌بر)، آن را در یک کلاس Fixture راه‌اندازی کنید و با IClassFixture<T> به تست‌ها تزریق نمایید. این کار زمان اجرای تست‌ها را کاهش و تکرار کد را حذف می‌کند.

    الگوی ICollectionFixture<T> و چرخه‌ی عمر

    برای اشتراک منبع در چند کلاس تست مرتبط از Collection Fixture استفاده کنید. این کار به جداسازی خوب، کنترل چرخه‌ی عمر، و جلوگیری از تداخل در موازی‌سازی کمک می‌کند.


    اجرای تست‌ها و پیکربندی

    اجرای dotnet test، فیلترگذاری، برچسب‌گذاری با Trait

    می‌توانید تست‌ها را با فیلتر اجرا کنید:

    dotnet test --filter "FullyQualifiedName~CalculatorTests"

    یا با برچسب‌گذاری ([Trait("Category","Fast")]) گروه‌بندی و فیلتر نمایید.

    لاگ و خروجی با ITestOutputHelper

    برای ثبت خروجی در طول اجرای تست از این واسط استفاده کنید تا عیب‌یابی سناریوهای پیچیده ساده‌تر شود.

    موازی‌سازی و کنترل برخوردها

    xUnit به‌صورت پیش‌فرض می‌تواند تست‌ها را موازی اجرا کند. اگر منبع مشترکی دارید که Thread-Safe نیست، موازی‌سازی را در سطح کالکشن یا پروژه غیرفعال کنید یا از Fixtureهای مناسب بهره بگیرید.


    تست یکپارچه‌سازی در دنیای واقعی

    تست سرویس‌های وب با WebApplicationFactory

    برای پروژه‌های ASP.NET Core، از کارخانه‌ی برنامه‌ی وب جهت بوت‌کردن میزبان تستی استفاده کنید و سپس با یک HttpClient درون‌فرآیندی درخواست‌ها را ارسال نمایید.

    پایگاه‌داده‌ی سبک (درون‌حافظه/SQLite) و جداسازی داده‌ها

    برای جلوگیری از آلودگی داده‌ها از پایگاه‌داده‌ی سبک و ایجاد/حذف اسکیما در هر سناریو استفاده کنید. این کار تست‌ها را قابل تکرار و سریع نگه می‌دارد.


    شبیه‌سازی وابستگی‌ها (Mock) و تست ایزوله

    برای ایزوله‌کردن واحد تحت تست، وابستگی‌ها را شبیه‌سازی کنید تا تنها منطق همان واحد سنجیده شود. این رویکرد باعث می‌شود تست‌ها پایدار، سریع و قابل اعتماد باشند.


    پوشش کد (Code Coverage) با ابزارهای متداول

    پوشش کد نشان می‌دهد چه بخش‌هایی از برنامه زیر بار تست قرار گرفته‌اند. می‌توانید با ابزارهای پوشش در کنار dotnet test گزارش‌های متنی/HTML تولید کنید و روند افزایش پوشش را در CI دنبال نمایید.


    ادغام در CI/CD (نمونه‌ی ساده‌ی گردش‌کار)

    — اجرای خودکار تست‌ها در هر Pull Request —

    چک‌اوِت کد

    نصب SDK

    بازیابی وابستگی‌ها

    بیلد

    اجرای تست‌ها

    انتشار گزارش‌ها

    شکست تست‌ها باید ادغام را متوقف کند تا کیفیت حفظ شود.


    بهترین شیوه‌ها و الگوهای نام‌گذاری

    اصل AAA (Arrange, Act, Assert)

    کد تست را به سه بخش واضح تقسیم کنید: چیدن داده‌ها و وابستگی‌ها، اجرای عمل، و راستی‌آزمایی خروجی. این چینش خوانایی و نگهداری را بهبود می‌دهد.

    اصل FIRST برای تست‌های خوب

    سریع، مستقل، قابل تکرار، خودتوصیف، و به‌موقع (درست‌هنگام). هرگاه تستی یکی از این ویژگی‌ها را از دست بدهد، دیر یا زود دردسرساز می‌شود.


    خطاهای رایج و راه‌حل‌ها

    به‌اشتراک‌گذاری وضعیت بین تست‌ها: از Fixture درست استفاده کنید یا موازی‌سازی را مدیریت کنید.

    تست‌های لرزان (Flaky): وابستگی به زمان/شبکه را حذف یا شبیه‌سازی کنید.

    نام‌گذاری مبهم: اسم تست باید انتظار شما را به‌روشنی بیان کند.


    نکات پیشرفته

    مرتب‌سازی و اولویت اجرای تست‌ها

    در موارد خاص می‌توان ترتیب اجرای تست‌ها را با مکانیزم‌های سفارشی مشخص کرد؛ با این حال توصیه می‌شود تست‌ها مستقل باشند تا به ترتیب وابسته نمانند.

    نظریه‌های داده‌محور پیچیده

    برای ورودی‌های بزرگ و پیچیده از MemberData/ClassData استفاده کنید تا هم خوانایی بالا بماند و هم موارد آزمون گسترده پوشش داده شود.


    مهاجرت از NUnit/MSTest به xUnit

    گام‌های پیشنهادی:

    برداشت موجودی تست‌ها

    نگاشت ویژگی‌های معادل ([Test][Fact] و …)

    جایگزینی Assertها

    انتقال Setup/TearDown به سازنده/Dispose یا Fixture

    اجرای تدریجی و موازی چارچوب‌ها تا تکمیل مهاجرت


    جمع‌بندی

    xUnit راهی ساده و مؤثر برای تضمین کیفیت در پروژه‌های دات‌نت است. با تکیه بر مفهوم تست‌های مستقل، داده‌محور و سریع، می‌توانید با اطمینان بازطراحی کنید و از نفوذ باگ‌ها جلوگیری نمایید. استفاده از Fixtureها، موازی‌سازی کنترل‌شده، پوشش کد، و ادغام در CI/CD، تصویری کامل از سلامت کد به شما می‌دهد. اگر تازه می‌خواهید چارچوب تست اصلی تیم‌تان را انتخاب کنید، xUnit ترکیبی خوش‌تعادل از سادگی، قدرت و جامعه‌ی کاربری بالغ را ارائه می‌کند.


    پرسش‌های متداول (FAQ)

    ۱) آیا xUnit برای پروژه‌های کوچک هم مناسب است؟
    بله؛ راه‌اندازی سریع و سادگی آن برای پروژه‌های کوچک ایده‌آل است و با رشد پروژه هم کم نمی‌آورد.

    ۲) فرق [Fact] و [Theory] در عمل چیست؟
    Fact یک سناریوی ثابت را می‌سنجد؛ Theory همان سناریو را با ورودی‌های مختلف امتحان می‌کند تا پوشش بیشتری بدهد.

    ۳) آیا می‌توان تست‌های یکپارچه‌سازی را هم با xUnit نوشت؟
    بله؛ با راه‌اندازی میزبان تستی وب و پایگاه‌داده‌ی سبک، سناریوهای سرتاسری را نیز می‌توان سنجید.

    ۴) چه زمانی موازی‌سازی را غیرفعال کنیم؟
    وقتی منبع مشترک Thread-Safe نیست یا ترتیب اجرای تست‌ها اهمیت دارد؛ در غیر این صورت موازی‌سازی زمان اجرا را کاهش می‌دهد.

    ۵) بهترین الگوی نام‌گذاری تست چیست؟
    الگوهای توصیفی مانند Method_Scenario_ExpectedResult خوانایی و هدف تست را واضح می‌کند (مثلاً: Add_NegativeNumbers_ReturnsCorrectSum).

     

    اطلاعات نویسنده
    • نویسنده: تیم تحریریه باگتو

    ارسال دیدگاه

    برای افزودن دیدگاه خود، نیاز است ابتدا وارد حساب کاربری‌تان شوید


    دیدگاه کاربران

    آموزش پیشنهادی باگتو


    course image

    Git در Visual Studio

    2,490,000 تومان


    اطلاعات بیشتر

    course image

    ستارگان سی شارپ

    9,900,000 تومان

    3,960,000 تومان


    اطلاعات بیشتر