اختبار في C#: Unit، Integration، E2E من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا نحتاج الاختبار في C#؟

\n

في التطوير الحديث باستخدام C# (.NET)، جودة الكود ليست رفاهية، بل ضرورة. لا يقتصر الاختبار على اكتشاف الأخطاء قبل الوصول إلى الإنتاج فحسب، بل يعمل أيضًا كتوثيق حي، ويسرّع عملية إعادة الهيكلة. هناك ثلاثة مستويات رئيسية للاختبار تشكل "هرم الاختبارات": Unit (الوحدة)، Integration (التكامل)، وE2E (الشامل). في هذه المقالة، سنشرح كل مستوى منها مع أمثلة من كود C# حقيقي.

\n\n

1. اختبار الوحدة: أساس الجودة

\n

تختبر اختبارات الوحدة جزءًا معزولًا من الكود (دالة، كلاس) بعيدًا عن التبعيات الخارجية (قواعد البيانات، نظام الملفات، API). في بيئة .NET، هناك ثلاثة أطر عمل شائعة: xUnit (موصى به للمشاريع الجديدة)، NUnit، وMSTest.

\n\n

المبادئ الأساسية (FIRST)

\n
    \n
  • Fast — سريعة (بالميلي ثانية).
  • \n
  • Isolated — معزولة (نستخدم الكائنات الوهمية).
  • \n
  • Repeatable — قابلة للتكرار.
  • \n
  • Self-validating — ذاتية التحقق (Assert).
  • \n
  • Timely — في الوقت المناسب.
  • \n
\n\n

مثال لاختبار وحدة باستخدام xUnit وMoq

\n

لنفترض أن لدينا خدمة لحساب الخصم:

\n
public interface IDiscountService\n{\n    decimal CalculateDiscount(decimal price, bool isLoyaltyMember);\n}\n\npublic class DiscountService : IDiscountService\n{\n    public decimal CalculateDiscount(decimal price, bool isLoyaltyMember)\n    {\n        if (isLoyaltyMember) return price * 0.9m; // خصم 10%\n        return price;\n    }\n}
\n

اختبار باستخدام Moq (لمحاكاة التبعيات) وxUnit:

\n
using Xunit;\nusing Moq;\n\npublic class DiscountServiceTests\n{\n    [Fact]\n    public void CalculateDiscount_WhenLoyaltyMember_ReturnsDiscountedPrice()\n    {\n        // ترتيب\n        var service = new DiscountService();\n        var price = 100m;\n\n        // تنفيذ\n        var result = service.CalculateDiscount(price, true);\n\n        // تأكيد\n        Assert.Equal(90m, result);\n    }\n\n    [Theory]\n    [InlineData(100, false, 100)]\n    [InlineData(200, true, 180)]\n    public void CalculateDiscount_MultipleCases_ReturnsCorrectValues(decimal price, bool isLoyalty, decimal expected)\n    {\n        var service = new DiscountService();\n        var result = service.CalculateDiscount(price, isLoyalty);\n        Assert.Equal(expected, result);\n    }\n}
\n

نصيحة: استخدم السمة [Fact] للاختبارات الفردية و[Theory] + [InlineData] للاختبارات المعلمة.

\n\n

2. اختبار التكامل: التحقق من ترابط المكونات

\n

تتحقق اختبارات التكامل من كيفية عمل عدة وحدات معًا - على سبيل المثال، وحدة التحكم، الخدمة، وقاعدة بيانات حقيقية (أو بديل لها، مثل SQLite في الذاكرة). في ASP.NET Core، يُستخدم WebApplicationFactory لهذا الغرض.

\n\n

إعداد WebApplicationFactory

\n

لننشئ كلاس اختبار يقوم بتشغيل مضيف ويب اختباري:

\n
using Microsoft.AspNetCore.Mvc.Testing;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\nusing MyApp.Data;\n\npublic class CustomWebApplicationFactory : WebApplicationFactory<Program>\n{\n    protected override void ConfigureWebHost(IWebHostBuilder builder)\n    {\n        builder.ConfigureServices(services =>\n        {\n            // إزالة DbContext الحقيقي\n            var descriptor = services.SingleOrDefault(\n                d => d.ServiceType == typeof(DbContextOptions<AppDbContext>));\n            if (descriptor != null) services.Remove(descriptor);\n\n            // إضافة قاعدة بيانات في الذاكرة\n            services.AddDbContext<AppDbContext>(options =>\n                

المدونات

توصيات الكتب