تصحيح أخطاء الاختبارات الفاشلة
اجعل حالات الفشل قابلة لإعادة الإنتاج، وأزل تأثير الوقت والعشوائية، واختزل المشكلة إلى حالة دنيا، وحسّن رسائل التوكيد لتشخيص سريع.
تصحيح أخطاء الاختبارات الفاشلة درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 3 دروس في المجموع.
خطة العمل
خطة لإصلاح الاختبارات الفاشلة:
- أعد إنتاج المشكلة بموثوقية
- أزل التذبذب (الوقت/العشوائية/الإدخال والإخراج)
- قلّص الحالة إلى أصغر مثال يفشل
- أضف رسائل تأكيد واضحة
التذبذب متوقع
يؤدي استخدام UtcNow وRandom الافتراضي إلى تغير السلوك بين عمليات التشغيل → اختبارات متذبذبة.
using System;
// Demo: occasionally fails because it depends on current second and default Random()
public static class Promo
{
// Gives bonus on even seconds; random adds small jitter
public static int BonusNow()
{
int baseBonus = (DateTime.UtcNow.Second % 2 == 0) ? 10 : 9;
Random r = new Random(); // time-based seed → unpredictable
return baseBonus + (r.Next(0, 2)); // 0 or 1 more
}
}
public class Program
{
public static void Main(string[] args)
{
// Simulated test: sometimes expects exactly 10, but result varies
int got = Promo.BonusNow();
if (got != 10) Console.WriteLine("FAIL (flaky): expected 10 but got " + got);
else Console.WriteLine("PASS (maybe): got " + got);
}
}
التحكم في الاعتمادات
احقن الوقت وRandom. وباستخدام بذرة ثابتة وطابع زمني ثابت، يصبح الفشل قابلاً لإعادة الإنتاج.
using System;
public interface IClock { DateTime NowUtc(); }
public sealed class FakeClock : IClock
{
private readonly DateTime _fixedUtc;
public FakeClock(DateTime fixedUtc) { _fixedUtc = fixedUtc; }
public DateTime NowUtc() { return _fixedUtc; }
}
public sealed class PromoDeterministic
{
private readonly IClock _clock;
private readonly Random _rng;
public PromoDeterministic(IClock clock, Random rng) { _clock = clock; _rng = rng; }
public int BonusNow()
{
int baseBonus = (_clock.NowUtc().Second % 2 == 0) ? 10 : 9;
return baseBonus + _rng.Next(0, 2);
}
}
public static class Assert
{
public static void AreEqual(int expected, int actual, string msg)
{
if (expected != actual) throw new Exception("Expected " + expected + " but got " + actual + " :: " + msg);
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
IClock clock = new FakeClock(new DateTime(2016, 1, 1, 0, 0, 20, DateTimeKind.Utc)); // even second
Random rng = new Random(123); // fixed seed
PromoDeterministic p = new PromoDeterministic(clock, rng);
int got = p.BonusNow(); // predictable now
Assert.AreEqual(10, got, "even second, first draw should be 0");
Console.WriteLine("PASS: deterministic promo");
}
catch (Exception ex)
{
Console.WriteLine("FAIL: " + ex.Message);
}
}
}
إعادة إنتاج مصغّرة
قلّص المدخلات حتى يفشل مثال صغير (هنا: مصفوفة فارغة). فالحالات الصغيرة أسهل في الفهم.
using System;
// Buggy function: average of ints, but divides by count without guarding empty input
public static class Stats
{
public static double Average(int[] xs)
{
int sum = 0;
for (int i = 0; i < xs.Length; i++) sum += xs[i];
return sum / xs.Length; // BUG: divide by zero if empty; also int division truncates
}
}
public static class Assert
{
public static void Throws<T>(Action a, string msg) where T : Exception
{
try { a(); }
catch (Exception ex)
{
if (ex is T) return;
throw new Exception("Expected " + typeof(T).Name + " but got " + ex.GetType().Name + " :: " + msg);
}
throw new Exception("Expected " + typeof(T).Name + " but no exception thrown :: " + msg);
}
}
public class Program
{
public static void Main(string[] args)
{
// Minimal failing case: empty array
Assert.Throws<DivideByZeroException>(delegate { Stats.Average(new int[0]); }, "empty input");
Console.WriteLine("Reproduced: empty input triggers the bug.");
}
}
جودة الإصلاح والرسائل
تحقّق من الإدخال غير الصالح، واستخدم رسائل تأكيد وصفية (تتضمن المدخلات/المتوقَّع/epsilon).
using System;
public static class Stats
{
public static double Average(int[] xs)
{
if (xs == null) throw new ArgumentNullException("xs");
if (xs.Length == 0) throw new ArgumentException("xs must not be empty", "xs");
double sum = 0.0; // use double to avoid integer truncation
for (int i = 0; i < xs.Length; i++) sum += xs[i];
return sum / xs.Length;
}
}
public static class Assert
{
public static void AreAlmostEqual(double expected, double actual, double eps, string msg)
{
if (Math.Abs(expected - actual) > eps)
throw new Exception("Expected " + expected + " but got " + actual + " (eps " + eps + ") :: " + msg);
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
double a = Stats.Average(new int[] { 2, 4, 6 });
Assert.AreAlmostEqual(4.0, a, 1e-9, "average of 2,4,6");
Console.WriteLine("PASS: fixed average with clear message");
}
catch (Exception ex)
{
Console.WriteLine("FAIL: " + ex.Message);
}
}
}
قائمة التحقق لتصحيح الأخطاء
قائمة التحقق لتصحيح الأخطاء:
- ثبّت الاعتمادات (الوقت والعشوائية والإدخال والإخراج)
- أعد إنتاج المشكلة محليًا وبشكل متكرر
- قلّص المدخلات إلى الحد الأدنى الذي يفشل
- أضف رسائل تأكيد دقيقة
- فضّل الدوال الصرفة وفحوص الحماية
الخطوة الأولى للاختبارات المتذبذبة
مراجعة
مراجعة: أعد إنتاج المشكلة بموثوقية عبر التحكم في الوقت والعشوائية، وقلّص المدخلات، واكتب رسائل تأكيد مفيدة لتحديد الخلل بسرعة.
الأسئلة الشائعة
هل درس «تصحيح أخطاء الاختبارات الفاشلة» مجاني؟
نعم — نص درس «تصحيح أخطاء الاختبارات الفاشلة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 3 دروس في المجموع.
ماذا ستتعلم في «تصحيح أخطاء الاختبارات الفاشلة»؟
اجعل حالات الفشل قابلة لإعادة الإنتاج، وأزل تأثير الوقت والعشوائية، واختزل المشكلة إلى حالة دنيا، وحسّن رسائل التوكيد لتشخيص سريع. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.
كم من الوقت يستغرق درس «تصحيح أخطاء الاختبارات الفاشلة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- إعداد xUnit/MSTest والتوكيدات
- التزييف عبر الواجهات ومنشئو بيانات الاختبار
- تصحيح أخطاء الاختبارات الفاشلة