طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 245 · ضمان جودة تطبيقات الويب
الدرس 5 · الوحدة 3: مراجعة التطبيقات وتحسينها

التقسيم المكافئ وتحليل القيم الحدّية

كيف نغطّي آلاف المدخلات بحفنة حالاتٍ مختارة بذكاء؟ ⏱ نحو 40 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تقسّم المدخلات إلى شرائح مكافئة.
  • تختبر ممثّلًا من كل شريحة.
  • تحلّل القيم الحدّية (الحدّ وجارتيه).
  • تدمج الأسلوبين لتغطيةٍ عالية بأقلّ حالات.

١لا تختبر كل قيمة: قسّمها

دالةٌ تقبل عمرًا من 0 إلى 120. أتختبر 121 قيمة؟ لا. التقسيم المكافئ Equivalence Partitioning يقسم المدخلات إلى فئاتٍ تتصرّف الدالة معها بالطريقة نفسها، فيكفي ممثّلٌ واحد من كل فئة.

الفئة (شريحة مكافئة)ممثّلالمتوقَّع
أقل من 0 (غير صالح)-5مرفوض
0 إلى 120 (صالح)45مقبول
أكبر من 120 (غير صالح)200مرفوض

ثلاث حالاتٍ تغطّي كل الاحتمالات سلوكيًّا، بدل 121. المبدأ: كل قيمةٍ في شريحةٍ واحدة تكشف ما تكشفه أخواتها، فلا داعي لتكرارها.

٢تحليل القيم الحدّية

التقسيم يختار ممثّلًا من وسط الشريحة، لكن العيوب على الحواف. لذا نكمّله بـ تحليل القيم الحدّية Boundary Value Analysis: اختبر القيمة الحدّية وجارتيها (الحدّ، وقبله، وبعده):

main.py
def is_valid_age(age):    return 0 <= age <= 120 # الحدود: حول 0 وحول 120boundaries = [-1, 0, 1, 119, 120, 121]expected  = [False, True, True, True, True, False]for age, exp in zip(boundaries, expected):    got = is_valid_age(age)    print(f"{'✓' if got == exp else '✗'}  عمر {age}: {got}")
Shell×
>>> %Run main.py
✓ عمر -1: False
✓ عمر 0: True
✓ عمر 1: True
✓ عمر 119: True
✓ عمر 120: True
✓ عمر 121: False
>>>

هذه الست قيمٍ تكشف أشهر عيبٍ: استخدام < بدل <=. لو كان الكود age < 120 لفشلت الحالة 120 فورًا.

٣دمج الأسلوبين: تغطية ذكية

معًا يعطيان تغطيةً عالية بأقلّ عدد: ممثّلٌ من كل شريحة + القيم الحدّية. انظر دالة خصمٍ بشرائح:

main.py
def discount_rate(qty):    "خصم حسب الكمية"    if qty <= 0:      return 0.0      # غير صالح    if qty < 10:      return 0.05     # شريحة صغيرة    if qty < 50:      return 0.10     # شريحة متوسطة    return 0.15                       # شريحة كبيرة # ممثّل + حدود كل شريحةcases = [(0, 0.0), (1, 0.05), (9, 0.05), (10, 0.10), (49, 0.10), (50, 0.15)]passed = sum(1 for q, exp in cases if discount_rate(q) == exp)print("نجح", passed, "من", len(cases), "— حدود الشرائح الثلاث مغطّاة")
Shell×
>>> %Run main.py
نجح 6 من 6 — حدود الشرائح الثلاث مغطّاة
>>>

توقّع وتحقّق

التقسيم المكافئ يقسم المدخلات إلى:

تحليل القيم الحدّية يختبر:

أشهر عيب تكشفه الحدود:

من كل شريحة مكافئة نختبر:

الخلاصة

تحدٍّ برمجي: غطِّ الشرائح

متوسط

دالة ship_fee: مجانًا فوق 200، و15 من 1 إلى 200، و0 للصفر أو أقل. اختبر الحالات المعطاة (تشمل الحدّ 200) واطبع عدد الناجحة.

المطلوب:
  • مرّ على الحالات وقارن.
  • اطبع عدد الحالات الناجحة.

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
def ship_fee(total):    if total <= 0: return 0    if total <= 200: return 15    return 0cases = [(0, 0), (1, 15), (200, 15), (201, 0), (500, 0)]# اطبع عدد الحالات الناجحة
المطلوب×
5
💡 تلميح 1
sum(1 for t, exp in cases if ship_fee(t) == exp).
💡 تلميح 2
الحالات تشمل الحدّ 200 و201 لكشف عيوب <= مقابل <.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
def ship_fee(total):    if total <= 0: return 0    if total <= 200: return 15    return 0cases = [(0, 0), (1, 15), (200, 15), (201, 0), (500, 0)]passed = sum(1 for t, exp in cases if ship_fee(t) == exp)print(passed)
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس