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

اختبار صحة المدخلات

أوّل باب تدخل منه العيوب هو المدخلات؛ كيف نختبر حرّاسه؟ ⏱ نحو 40 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تختبر قبول الصالح ورفض الفاسد.
  • تطبّق تحليل الحدود على قواعد التحقّق.
  • تختبر المدخلات المتطرّفة.
  • تدرك التحقّق كخطّ دفاعٍ أمنيّ.

١المدخلات أوّل مصدر للأعطال

معظم عيوب تطبيقات الويب تدخل من المدخلات: نموذجٌ يقبل بريدًا بلا @، سعرًا سالبًا، نصًّا طويلًا يكسر القاعدة. اختبار صحة المدخلات يتأكّد أن التطبيق يقبل الصالح ويرفض الفاسد — وهو من صميم «اختبار صحة البيانات» في مواصفة هذا المقرر.

لكل حقلٍ عقدٌ نختبره: النوع، والشكل، والمدى، والطول، والقيم المسموحة. ولكلٍّ نكتب حالاتٍ صالحةً وفاسدة:

main.py
def validate_email(e):    return isinstance(e, str) and "@" in e and "." in e.split("@")[-1] cases = [    ("a@b.sa",   True),      # صالح    ("a@b",      False),     # بلا نقطة في النطاق    ("ab.sa",    False),     # بلا @    ("",         False),     # فارغ    ("x@y.com",  True),]passed = sum(1 for e, exp in cases if validate_email(e) == exp)print("نجح", passed, "من", len(cases))
Shell×
>>> %Run main.py
نجح 5 من 5
>>>

٢اختبار الحدود في التحقّق

التحقّق مليءٌ بالحدود: الطول الأدنى والأقصى، أصغر وأكبر قيمة. نطبّق تحليل القيم الحدّية (الدرس 5) على قواعد التحقّق:

main.py
def validate_username(u):    return isinstance(u, str) and 3 <= len(u) <= 20 # حدود الطول: 2 و3 و20 و21cases = [("ab", False), ("abc", True), ("a"*20, True), ("a"*21, False)]for u, exp in cases:    got = validate_username(u)    print(f"{'✓' if got == exp else '✗'}  طول {len(u)}: {got}")
Shell×
>>> %Run main.py
✓ طول 2: False
✓ طول 3: True
✓ طول 20: True
✓ طول 21: False
>>>

الحالتان 3 و20 (الحدّان المقبولان) و2 و21 (المرفوضان) تكشفان عيب < مقابل <= في قاعدة الطول.

٣المدخلات الخبيثة أيضًا

التحقّق خطّ دفاعٍ أمنيّ (تذكّر مقرر أمن الويب): اختبر أن النموذج يرفض أو يطهّر المدخلات الخطرة لا الفاسدة فقط:

main.py
def clean_name(name):    "يرفض الفراغ، ويزيل المسافات الطرفية، ويحدّ الطول"    name = name.strip()    if not name or len(name) > 50:        return None    return name cases = [    ("  سارة  ", "سارة"),       # يُنظَّف    ("", None),                  # فارغ يُرفَض    ("a" * 60, None),            # طويل يُرفَض]passed = sum(1 for inp, exp in cases if clean_name(inp) == exp)print("نجح", passed, "من", len(cases), "— يقبل الصالح ويرفض الفاسد")
Shell×
>>> %Run main.py
نجح 3 من 3 — يقبل الصالح ويرفض الفاسد
>>>

توقّع وتحقّق

أكثر العيوب تدخل من:

لكل حقلٍ نختبر الصالح و:

اختبار طول اسمٍ عند 3 و20 هو اختبار:

التحقّق من المدخلات أيضًا:

الخلاصة

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

متوسط

الدالة valid_qty تقبل عددًا صحيحًا من 1 إلى 100. اختبرها على الحالات المعطاة (تشمل الحدّين 1 و100) واطبع عدد الناجحة.

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

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

main.py
def valid_qty(q):    return isinstance(q, int) and 1 <= q <= 100cases = [(1, True), (100, True), (0, False), (101, False), (50, True)]# اطبع عدد الحالات الناجحة
المطلوب×
5
💡 تلميح 1
sum(1 for q, exp in cases if valid_qty(q) == exp).
💡 تلميح 2
الحالات تشمل الحدّين 1 و100 و0 و101.

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

main.py
def valid_qty(q):    return isinstance(q, int) and 1 <= q <= 100cases = [(1, True), (100, True), (0, False), (101, False), (50, True)]passed = sum(1 for q, exp in cases if valid_qty(q) == exp)print(passed)
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

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