محتويات الدورة

ASP.NET Core / المتقدم: التحقق والتشغيل الموثوق / الدرس 13

الاختبار وحدود الدليل

اختر اختبارات الوحدة والمكون والتكامل ومزوّد البيانات والنشر بحسب العقد الذي يجب أن يثبته كل منها.

وقت القراءة التقريبي: 5 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • اشتق توقعات الحدود والفشل من مرجع حكم مستقل.
  • تحقق من أن رفض العملية يترك آثارها دون تنفيذ.
  • ميز تنفيذ المكون في الذاكرة من اختبارات HTTP المستضافة واختبارات SQL.

يحتاج الاختبار إلى ادعاء ومرجع حكم مستقل

ابدأ بالسلوك الذي تتعهد به، لا بسطر التنفيذ الذي تريد تغطيته. حدد الحالة والحمولة والآثار والملكية وسياسة الفشل. ينبغي أن يكون مرجع الحكم نتيجة معلومة أو خاصية مستقلة، لا نسخة من تعبير الشفرة الإنتاجية. تقيس التغطية الشفرة التي نُفذت، لكنها لا تبين ما إذا جرى التحقق من توقعات ذات معنى.

استخدم عينات اصطناعية صغيرة مع مزوّدين وساعات وهويات وإعدادات محددة صراحة. تجنب الاختبارات التي تقرأ بيئة تطبيق قائم مهيأ أو بيانات اعتماده أو قاعدته بصمت. يسهل تشخيص فشل حتمي أكثر من اختبار شامل تتغير اعتمادياته الخارجية بصورة مستقلة.

تحقق من وقوع الرفض قبل تنفيذ الأثر

يستدعي البرنامج الكامل الأول مفوّض طلب محليا بمدخل غير صالح وأثر اصطناعي معدود. يشترط الحالة 400 وعدم وقوع أي استدعاء ملتزم. يثبت ذلك الحارس الصريح في المفوّض نفسه، ولا يختبر ربط Minimal API أو المرشحات أو التحقق التلقائي في MVC. يجعل هذا التمييز التأكيد السلبي مفيدا دون المبالغة في تغطية التكامل.

ضم مدخلا صالحا والقيم الواقعة على الحدود بدقة والمدخل المفقود والقيم المشوهة ومسار فشل الأثر. قد ينجح اختبار الحالة وحدها بعد تحديث غير مقصود. وللسلوك المعتمد على مزوّد بيانات، استخدم اختبار مزوّد معزولا ومأذونا بدلا من اعتبار List أو قاموس دليلا على دلالات المعاملات والقيود.

csharp التحقق من عقد رفض محلي يسبق الأثر
using System;
using System.Globalization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

int effects = 0;
RequestDelegate handler = context =>
{
    string? token = context.Request.Query["quantity"];
    if (!int.TryParse(token, NumberStyles.None, CultureInfo.InvariantCulture, out int value) || value is < 1 or > 10)
    { context.Response.StatusCode = 400; return Task.CompletedTask; }
    effects++;
    context.Response.StatusCode = 202;
    return Task.CompletedTask;
};
var context = new DefaultHttpContext();
context.Request.QueryString = new QueryString("?quantity=0");
await handler(context);
if (context.Response.StatusCode != 400 || effects != 0) throw new InvalidOperationException("rejection contract failed");
Console.WriteLine($"status={context.Response.StatusCode} effects={effects}");
الناتج المتوقع
status=400 effects=0

يرفض المفوّض الصريح الصفر قبل زيادة عداد الأثر؛ ولا تعمل منظومة ربط أو قاعدة بيانات.

يشمل اختبار تكامل المضيف التطبيق المركب فعليا

يمكن أن تدعم WebApplicationFactory وTestServer تكامل إطار معزولا عند توفر حزم الاختبار الموثوقة المناسبة. تستطيع هذه الاختبارات تشغيل التوجيه والربط والمرشحات وعينات مخطط المصادقة والتسلسل وسلوك الرد. لكنها ما زالت تحتاج استبدالا مقصودا للاعتماديات، ولا تتحقق تلقائيا من وكيل الإنتاج أو TLS أو قاعدة حقيقية أو نشر سحابي.

لا يثبت المقرر تلك الحزم ولا يبدأ مضيف اختبار. يجب أن تبقى مقاطع التكامل غير المنفذة غير قابلة للتشغيل. يفيد اختبار متحكم أو نتيجة مباشرة، لكن العقد العام يحتاج أيضا حالات الطريقة الخاطئة والمسار المفقود والطلب غير المصادق والممنوع والمشوه عند حد الإطار حين تتاح تلك البيئة.

اختبر الاكتمال والتخلص بوصفهما خاصيتين ملحوظتين

يحقن البرنامج الكامل الثاني بديلا وهميا مملوكا يملك علم اكتمال، ويراقب استخدامه غير المتزامن قبل التخلص منه. يؤكد النتيجة المفيدة وانتهاء الاستعارة معا. هذه وحدة لدورة الحياة، وليست دليلا عن EF أو اتصال شبكي. ينبغي أن يكشف البديل الخاصية المختبرة دون محاكاة كل تفاصيل التنفيذ.

استخدم إشارات اكتمال صريحة للاختبارات التي تحتاج ضبط الجدولة. لا يصلح نوم أطول سباقا ولا يثبت توقف عامل. تحمي مهل الاختبار المحدودة من التعليق، بينما يظل التنفيذ مطالبا بالإيقاف والانتظار حتى الانتهاء والتنظيف. ويجب ألا تتشارك الاختبارات المتوازية عينات عامة قابلة للتعديل.

csharp مراقبة الاكتمال قبل التخلص من المورد المملوك
using System;
using System.Threading.Tasks;

var dependency = new FakeDependency();
int value;
using (dependency) { value = await dependency.ReadAsync(); }
if (value != 7 || !dependency.Completed || !dependency.Disposed) throw new InvalidOperationException("lifetime contract failed");
Console.WriteLine($"value={value} completed={dependency.Completed} disposed={dependency.Disposed}");

internal sealed class FakeDependency : IDisposable
{
    public bool Completed { get; private set; }
    public bool Disposed { get; private set; }
    public async Task<int> ReadAsync() { await Task.Yield(); if (Disposed) throw new ObjectDisposedException(nameof(FakeDependency)); Completed = true; return 7; }
    public void Dispose() => Disposed = true;
}
الناتج المتوقع
value=7 completed=True disposed=True

ينتهي البديل من قراءة 7 قبل التخلص، وتتحقق التأكيدات من علمي دورة الحياة معا.

أبلغ عما اختُبر وما بقي خارج نطاقه

احفظ المصدر وإصدارات الإطار وخيارات المشروع والمدخلات والمخرجات المتوقعة وبدائل الاعتماديات. افصل في التقرير فحص الترجمة والتنفيذ المباشر للمكون والتكامل المستضاف واختبارات المزوّد والتحقق من النشر. لا تستطيع مجموعة محلية ناجحة اعتماد كل حد ثقة أو حالة فشل تشغيلي.

احتفظ باختبارات تراجع للسلوك المفيد الذي أصلحته، وشغّل الفحوص الملائمة للتغييرات. وسّع الاختبارات حين تبرر ذلك إخفاقات جديدة أو مخاطر لم تُحسم، لا بتكرار أحمال قديمة مكلفة للمظهر فقط. راجع بيان التحقق بعناية مراجعة التنفيذ نفسه حتى لا يخلط المستهلك اختبارا ضيقا مفيدا بإثبات شامل.

الأخطاء الشائعة وإصلاحها

يفحص اختبار سلبي الحالة لكنه يتجاهل الحالة المخزنة الملتزم بها.

لماذا يحدث؟
لم يدخل حد الأثر ضمن مرجع الحكم.
كيف تصلحه؟
أكد الرفض المقصود وغياب الآثار الجانبية معا.
كيف تتجنب تكراره؟
استخدم اعتمادية اصطناعية معدودة الاستدعاءات أو قابلة للضبط.

يوصف اختبار فعل مباشر بأنه تكامل API كامل.

لماذا يحدث؟
جرت المبالغة في الطبقة المختبرة.
كيف تصلحه؟
سجل بدقة مكونات الإطار التي نُفذت فعلا.
كيف تتجنب تكراره؟
احتفظ بتغطية تكامل منفصلة للسلوك العام.

تضيف اختبارات الإلغاء المتذبذبة فترات نوم.

لماذا يحدث؟
استُبدلت ملكية الاكتمال بتخمين التوقيت.
كيف تصلحه؟
استخدم إشارات صريحة وحواجز اختبار محدودة.
كيف تتجنب تكراره؟
أكد التنظيف بعد ملاحظة الاكتمال.

اختبر فهمك

1. يستدعي اختبار فعل متحكم فيجد NotFoundResult. ما الادعاءات التي يدعمها، وأيها يحتاج دليلا إضافيا؟

اعرض الحل المشروح

يدعم فرع الفعل والنية المعادة لذلك المدخل الاصطناعي. لا يثبت مطابقة المسار أو الربط أو مرشحات ApiController أو المصادقة أو التسلسل المتفاوض عليه أو تسليم رد 404 فعلي. احتفظ باختبار الوحدة وأضف تكامل إطار معزولا مناسبا لتلك السلوكيات العامة. ينبغي وصف الاختبار الضيق المفيد ضمن حدوده، لا التخلص منه أو تضخيم دلالته.

2. لماذا لا ينبغي استخدام اختبار مستودع وهمي لاعتماد ترحيل جديد لرمز التزامن في EF؟

اعرض الحل المشروح

لا ينفذ البديل مخطط المحرك المستهدف أو ترجمة المزوّد أو شروط التحديث أو عزل المعاملة أو سلوك التعارض. استخدم ترحيلا مراجعا واختبارات مزوّد معزولة ومأذونة لتلك الادعاءات، مع إبقاء اختبارات وحدة سياسة تعارض المجال منفصلة. لا يعوض نجاح طبقة دليلا مفقودا من طبقة أخرى.

أهم ما تعلمته

  • يحدد الاختبار المفيد ادعاءه ومرجع حكمه وآثاره.
  • تحتاج المكونات المباشرة وتكامل المضيف ومزوّدو البيانات والنشر إلى أدلة مختلفة.
  • يجب أن تلاحظ الاختبارات غير المتزامنة الاكتمال قبل التنظيف.

المراجع الرسمية