عنوان:

‫کشف حالت‌های مرزی (Edge Cases) و سناریوهای شکست با شبیه‌سازی نگاه نقادانه


نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۵/۲۹ ۱۲:۱۳
آدرس: www.dntips.ir
توسعه‌دهندگان به‌طور طبیعی تمایل دارند کدها را بر مبنای «مسیر موفقیت» (Happy Path) بنویسند و ارزیابی کنند. نقطه ضعف این رویکرد، پنهان ماندن رفتارهای پیش‌بینی‌نشده در مواجهه با خطاهای شبکه، همزمانی‌ها و ورودی‌های نامعتبر است. استفاده از GitHub Copilot نه صرفاً برای تکمیل خودکار، بلکه به‌عنوان یک «طراح آزمون سخت‌گیر و مهاجم» (Hostile Test Designer)، کمک می‌کند تا پیش‌فرض‌های ضمنی کد استخراج شده و سناریوهای شکست قبل از ورود به محیط عملیاتی شناسایی شوند.
درخواست‌های کلی مانند «Write unit tests» عموماً همان مسیر موفق را تست می‌کنند؛ در حالی که تعیین یک چارچوب ارزیابی تهاجمی، مدل را به سمت تحلیل گلوگاه‌ها هدایت می‌کند.

چارچوب پرامپت ارزیابی تهاجمی برای Endpointها و سرویس‌ها

هنگام اعتبارسنجی یک متد، لایه سرویس یا Endpoint، از الگوی تحلیلی زیر استفاده کنید:
این متد را از دیدگاه یک مهندس تضمین کیفیت سخت‌گیر (QA/Security Reviewer) تحلیل کن.
سناریوهای زیر را بررسی و بر اساس شدت ریسک (Severity) رتبه‌بندی کن:
  • مقادیر تهی (null) یا رشته‌ها و مجموعه‌های خالی
  • مقادیر مرزی نامعتبر (مانند شناسه‌های منفی یا صفر)
  • درخواست‌های تکراری و متوالی (Idempotency و Race Conditions)
  • وضعیت‌های همزمانی (Concurrency Conflicts)
  • ورودی‌های ناقص یا با ساختار خراب (Malformed Payloads)
  • سناریوهای وقفه زمانی (Timeouts) و لغو درخواست توسط کاربر
  • خطاهای زیرساختی (قطعی دیتابیس یا سرویس‌های شخص ثالث)
  • ردیابی تغییرات غیرضروری و افشای اطلاعات لایه‌های داخلی

کالبدشکافی یک متد ساده در #C

متد اولیه زیر را در نظر بگیرید:
public async Task<Order> GetOrderAsync(int id)
{
    return await _db.Orders
        .FirstOrDefaultAsync(x => x.Id == id);
}
پرسش تحلیلی هدفمند:
«این متد چه پیش‌فرض‌های پنهانی را در نظر گرفته است؟ حداقل ۱۰ سناریوی شکست، ابهام منطقی و گلوگاه کارایی آن را فهرست کن.»
بررسی مهندسی حاصل از این تحلیل، موارد زیر را آشکار می‌سازد:
  • ابهام در تایپ بازگشتی (Nullability): خروجی متد Task تعریف شده در حالی که FirstOrDefaultAsync در صورت عدم وجود رکورد، مقدار null بازمی‌گرداند. این موضوع قرارداد متد را نقض کرده و باعث هشدارهای NRT (Nullable Reference Types) می‌شود.
  • ورودی‌های نامعتبر: ارسال مقادیر نامعتبر مانند id <= 0 به جای بازگرداندن پاسخ مشخص یا خطای اعتبارسنجی، مستقیماً به پایگاه داده کوئری می‌زند.
  • فقدان مکانیزم لغو عملیات (CancellationToken): در صورت قطع ارتباط کاربر یا بروز Timeout، کوئری در پس‌زمینه دیتابیس اجرا شده و منابع سرور را هدر می‌دهد.
  • ردیابی غیرضروری تغییرات (Change Tracking): برای یک متد واکشی صرف (Read-only)، استفاده از ردیابی پیش‌فرض EF Core بار حافظه و پردازش اضافی ایجاد می‌کند.
  • وابستگی به داده‌های مرتبط: مشخص نیست که آیا متعلقات سفارش (مانند OrderItems) باید با Include بارگذاری شوند یا خیر.

بازنویسی متد بر اساس تحلیل سناریوهای مرزی

با اعمال اصلاحات ناشی از کشف حالت‌های مرزی، پیاده‌سازی به شکلی امن، پایدار و بهینه بازنویسی می‌شود:
public async Task<OrderResponseDto?> GetOrderAsync(
    int id, 
    CancellationToken cancellationToken = default)
{
    // ۱. بررسی مقادیر نامعتبر بدون درگیر کردن پایگاه داده
    if (id <= 0)
    {
        return null;
    }

    // ۲. استفاده از AsNoTracking برای کوئری‌های صرفاً خواندنی
    // ۳. ارسال CancellationToken جهت جلوگیری از اجرای بی‌فایده کوئری
    // ۴. Projection مستقیم به DTO جهت کاهش حجم بارگذاری حافظه و جلوگیری از افشای Domain Model
    var orderDto = await _db.Orders
        .AsNoTracking()
        .Where(x => x.Id == id)
        .Select(x => new OrderResponseDto(
            x.Id,
            x.OrderDate,
            x.TotalAmount,
            x.Status))
        .FirstOrDefaultAsync(cancellationToken);

    return orderDto;
}

نکات تکمیلی برای افزایش استحکام سیستم

  • شبیه‌سازی سناریوهای Idempotency: هنگام تحلیل اکشن‌های POST یا پرداخت‌ها، از Copilot بخواهید روش برخورد با درخواست‌های هم‌زمان که شناسه تکراری (Idempotency Key) ارسال می‌کنند را تحلیل کند.
  • بررسی رفتار لغو (Cancellation Propagation): متدهای واکشی و تغییر داده را ملزم کنید تا همیشه تست‌های پرتاب OperationCanceledException را پاس کنند.
  • تفکیک خطاهای بیزینس از خطاهای سیستمی: از مدل بخواهید بررسی کند که آیا عدم وجود داده (Not Found) با خطای قطعی زیرساخت (Database Failure) تفکیک شده است یا خیر.

قاعده کلیدی: کدنویسی صرفاً پیاده‌سازی جریان‌های بدون نقص نیست؛ پرسش از سناریوهای خرابی، هوش مصنوعی را از یک تکمیل‌کننده متن به ابزاری برای ارتقای معماری و تاب‌آوری سیستم تبدیل می‌کند.