اختبار نماذج الويب
يجمع نموذج الويب (Web Form) مدخلات المستخدم ويرسلها إلى الخادم، كما في نماذج التسجيل وإتمام الشراء والحجز والتواصل. واختباره يعني التحقق من أن كل حقل يقبل ما يجب قبوله ويرفض ما يجب رفضه، وأن كل رفض يشرح سببه، وأن الإرسال ينفّذ أمراً واحداً مرة واحدة بالضبط، وأن الخادم يخزّن ما أدخله المستخدم.
وتُفحص مدخلات النموذج عادةً على طبقتين. فالتحقق من جهة العميل (Client-side Validation) يجري في المتصفح قبل إرسال أي شيء: اترك حقل البريد الإلكتروني فارغاً وسيوقفك المتصفح. والتحقق من جهة الخادم (Server-side Validation) يجري عند وصول الطلب: فالخادم وحده يعرف أن هذا البريد مسجّل مسبقاً. والمختبِر يفحص الطبقتين.
لماذا يهم
النماذج هي المكان الذي يسلّم فيه المستخدمون بياناتهم وأموالهم. فالنموذج الذي يرفض اسماً صحيحاً فيه فاصلة علوية يخسر عميلاً، والنموذج الذي يحجز مرتين عند النقر المزدوج يستهلك المقاعد أو يحصّل المبلغ مرتين. وتفلت هذه العيوب حين لا يُجرَّب إلا عدد قليل من القيم المرتبة.
ومن السهل أيضاً تجاوز فحوص جهة العميل. فورقة OWASP المرجعية للتحقق من المدخلات (Input Validation Cheat Sheet) تشترط التحقق على الخادم، لأن أي فحص يجري في المتصفح يمكن الالتفاف عليه. وقد يبدو النموذج صارماً بينما يقبل الخادم خلفه أي شيء، ولا يكتشف ذلك إلا مختبِر يتجاوز المتصفح.
التحقق من جهة العميل ومن جهة الخادم
يستخدم التحقق من جهة العميل قيود HTML التي رأيتها في درس HTML للمختبِرين، مثل required وtype="email" وmaxlength، إضافةً إلى شيفرات الصفحة التي تفحص الحقل أثناء الكتابة أو عند مغادرته. وهو يقدّم ملاحظات سريعة لكنه لا يحمي شيئاً: فأي شخص يستطيع حذف سمة، أو تعطيل JavaScript، أو إرسال الطلب دون الصفحة.
أما التحقق من جهة الخادم فهو الإلزام الفعلي. يجب أن يكرر كل قاعدة من قواعد العميل، وهو وحده القادر على فحص القواعد التي تحتاج إلى بيانات مخزّنة، مثل البريد غير المكرر أو المقاعد المتبقية. اختبر كل قاعدة عبر النموذج للتحقق من تجربة المستخدم، ومن خارجه للتحقق من الإلزام، على نظام مسموح لك باختباره:
- في أدوات المطور (DevTools) احذف
requiredأوmaxlength، أو أضفnovalidateإلى<form>لتعطيل فحوص المتصفح المدمجة، ثم أرسل. يبقى التعديل في تبويبك وحده، لكن الطلب حقيقي. - أو انسخ الطلب من لوحة Network بصيغة cURL، وغيّر قيمة واحدة، وأرسله مجدداً بحساب اختبار من الطرفية (Terminal) أو من أداة «منشئ طلبات API»؛ ويقسّم «محلّل أوامر cURL» الأمر إلى الطريقة وعنوان URL والترويسات والجسم. المتوقع: استجابة من الفئة 4xx مثل
422، وتسمية الحقل، وعدم حفظ أي شيء. - قارن مجموعتي القواعد. فالخادم الأشد من الصفحة (الصفحة تسمح بـ 100 حرف وعمود قاعدة البيانات يتسع لـ 50) يظهر في صورة خطأ 500 أو نص مقطوع بصمت، والصفحة الأشد من الخادم (نمط بريد يرفض
+) تحجب مستخدمين حقيقيين.
عبر النموذج
- المستخدم
- المتصفح التحقق من جهة العميل
- الخادم التحقق من جهة الخادم
- 1 من المستخدم إلى المتصفح: ينقر «تسجيل» والاسم الكامل فارغ
- 2 المتصفح داخليًا: يفشل فحص
required: لا يُرسَل أي طلب - 3 من المتصفح إلى المستخدم: رسالة عند حقل الاسم الكامل ردّ
- 4 من المستخدم إلى المتصفح: يصحّح الاسم وينقر «تسجيل» مجدداً البريد
sara@example.comمسجّل مسبقاً - 5 المتصفح داخليًا: تنجح فحوص جهة العميل
- 6 من المتصفح إلى الخادم: يرسل التسجيل
POST /events/42/registrations - 7 الخادم داخليًا: يكرر القواعد ويفحص التسجيلات المخزّنة الخادم وحده يعرف أن البريد مستخدم
- 8 من الخادم إلى المتصفح: 422: البريد مسجّل مسبقاً ردّ
{"field":"email","code":"already_registered"} - 9 من المتصفح إلى المستخدم: رسالة تحت حقل البريد، وبقاء المدخلات ردّ
النتيجة: يقدّم المتصفح ملاحظات فورية؛ أما القواعد التي تحتاج إلى بيانات مخزّنة فلا تُفحص إلا على الخادم.
حول النموذج
- المختبِر
- المتصفح التحقق من جهة العميل
- الخادم التحقق من جهة الخادم
- 1 من المختبِر إلى الخادم: يعيد إرسال الطلب دون الصفحة منسوخ بصيغة cURL: اسم من مسافات، و5 تذاكر
{"name":" ","tickets":5} - 2 الخادم داخليًا: يكرر كل قاعدة من قواعد العميل يحذف المسافات من الاسم ويقبل من 1 إلى 4 تذاكر
- 3 من الخادم إلى المختبِر: 422، مع تسمية الحقلين، ولا يُحفظ شيء ردّ نجاح
النتيجة: المتوقع: يرفض الخادم بنفسه. واستجابة 201 هنا تعني أنه يثق بالمتصفح، وهذا عيب.
الحقول الإلزامية والمدخلات الإيجابية والسلبية
تحقق من أن كل حقل إلزامي معلَّم على الشاشة وفي الشيفرة، وأن كل حقل ناقص يُبلَّغ عنه. ورسائل المتصفح المدمجة لا تُظهر عادةً إلا أول حقل غير صالح في كل مرة؛ فإن طلب المتطلب عرض كل الأخطاء معاً، احتاجت الصفحة إلى شيفرة خاصة بها تسردها. والحقل النصي الذي لا يحوي إلا مسافات يجتاز فحص required في المتصفح، لذا يجب أن يحذف الخادم المسافات ويرفضه. ويجب أن يُخزَّن الحقل الاختياري المتروك فارغاً على أنه فارغ، لا بالنص null؛ والحقول الإلزامية المشروطة، مثل الرقم الضريبي لحسابات الشركات فقط، تحتاج إلى اختبار حالتيها.
ثم طبّق الاختبار الإيجابي والسلبي حقلاً حقلاً، فالبيانات الصالحة الحقيقية أكثر تنوعاً مما يتوقعه المطورون:
- إيجابي:
O'BrienوAl-Harbi، وأسماء بالعربية وبالديفاناغارية، وsara+events@example.com، ورقم هاتف ملصوق بمسافات مثل+966 50 123 4567. - سلبي: حقل فارغ، ومسافات فقط، وحرف واحد فوق الحد الأقصى، و
sara@، وحروف في حقل رقمي، و0 حيث الحد الأدنى 1. - النص الذي يشبه وسوم HTML، مثل
<b>Sara</b>، يجب أن يُخزَّن ويُعرض كما كُتب، ولا يظهر بخط عريض أبداً؛ ويتعمق درس أساسيات أمان الويب في ذلك. - الأرقام العربية المشرقية مثل
٠٥٠١٢٣٤٥٦٧في حقل الهاتف: تُحوَّل أو تُرفض برسالة واضحة، بحسب ما يقوله المتطلب. وإن لم يذكر شيئاً فاسأل.
جرّبها: مولّد اختبارات التحقق جرّبها: مولّد الاختبارات السلبية جرّبها: مولّد مجموعات بيانات Unicode
رسائل الخطأ والإرسال والإرسال المزدوج
رسالة الخطأ جزء من النتيجة المتوقعة: تظهر بجوار حقلها، وتقول ما يجب فعله («أدخل بريداً مثل name@example.com» لا «إدخال غير صالح»)، وتحافظ على ما كتبه المستخدم، وتختفي بعد تصحيح الحقل. ويجب أن تبدو أخطاء الخادم مثل أخطاء العميل وأن تستخدم لغة الصفحة؛ أما رسائل المتصفح المدمجة فتتبع لغة المتصفح. ويشرح دليل النماذج القابلة للوصول كيف تُعلَن الأخطاء.
يجب أن يؤدي الإرسال أمراً واحداً مرة واحدة: يظهر مؤشر التقدم، ويعرض النجاح تأكيداً ويخزّن سجلاً واحداً بالضبط، ويحافظ الإخفاق، بما فيه انقطاع الاتصال، على المدخلات. والضغط على Enter في حقل من سطر واحد يرسل النموذج عادةً أيضاً. ولا يعرّف RFC 9110 الطريقة POST بأنها متساوية الأثر (Idempotent): فقد يكون لطلبَي POST متطابقين أثر أكبر من أثر طلب واحد، لذا قد يُنشئ إرسال النموذج نفسه مرتين سجلين. بعد إبطاء الشبكة في أدوات المطور جرّب ما يلي:
- انقر زر الإرسال نقراً مزدوجاً، أو اضغط Enter مرتين.
- أعد تحميل صفحة التأكيد: يعرض المتصفح إرسال البيانات مرة أخرى. وكثير من المواقع يمنع ذلك بإعادة التوجيه بعد POST إلى صفحة تُحمَّل بالطريقة GET.
- ارجع للخلف وأرسل مجدداً، أو أرسل النموذج نفسه من تبويبين.
- المتوقع: سجل واحد وبريد واحد. تعطيل الزر يوقف معظم النقرات المزدوجة، لكنه لا يوقف إعادة التحميل ولا التبويب الثاني ولا الطلب المُعاد إرساله، لذا يحتاج الخادم إلى فحص خاص به للتكرار.
الملء التلقائي ومديرو كلمات المرور
كثير من المستخدمين لا يكتبون أصلاً: فالمتصفح أو مدير كلمات المرور يملأ النموذج من بيانات محفوظة. وتخبره السمة autocomplete بنوع كل حقل، برموز من معيار HTML مثل name وemail وtel وnew-password؛ ويتوقع معيار النجاح 1.3.5 «تحديد غرض الإدخال» (Identify Input Purpose) في WCAG 2.2 وجودها في الحقول التي تجمع معلومات عن المستخدم. احفظ بيانات اختبار في ملف تعريف منفصل للمتصفح، ثم تحقق مما يلي:
- تصل كل قيمة إلى الحقل الصحيح، فلا يقع الاسم الكامل في «الاسم الأول».
- يتفاعل التحقق وزر الإرسال مع القيم المملوءة: فكما رأيت في درس JavaScript للمختبِرين، الفحص الذي يستمع لضغطات المفاتيح فقط لا يعمل بعد الملء التلقائي.
- تقبل حقول تسجيل الدخول اللصق ومديري كلمات المرور. فمنعهما يجبر الناس على كتابة كلمات المرور من الذاكرة، وهذا ما وُضع معيار النجاح 3.3.8 «المصادقة الميسّرة (الحد الأدنى)» (Accessible Authentication (Minimum)) في WCAG 2.2 لمنعه.
جرّبها: مولّد مستخدمين وهميين جرّبها: مولّد أرقام هواتف وهمية
مثال تطبيقي: نموذج التسجيل في فعالية
المتطلب: «للتسجيل في فعالية مجانية أدخل الاسم الكامل (إلزامي، من 2 إلى 60 حرفاً)، والبريد الإلكتروني (إلزامي، تسجيل واحد لكل بريد)، والجوال (إلزامي، 05 ثم 8 أرقام)، والشركة (اختياري)، والتذاكر (من 1 إلى 4، ضمن المقاعد المتبقية). ويعرض زر «تسجيل» رقماً مرجعياً ويرسل بريداً». يستطيع المتصفح فحص الوجود والطول والصيغة والنطاق، أما الخادم فوحده يعرف أي عناوين البريد مسجّلة وكم مقعداً بقي.
- RF-01، إيجابي: بيانات صالحة ← رقم مرجعي، وسجل واحد، وبريد واحد.
- RF-02، إيجابي:
نورة القحطانيوnora+expo@example.comدون شركة ← مقبول ويُعرض كما أُدخل. - RF-03، سلبي، المتصفح: «تسجيل» وكل الحقول فارغة ← الإبلاغ عن كل حقل إلزامي، ولوحة Network لا تُظهر أي طلب.
- RF-04، سلبي، الخادم: إعادة إرسال الطلب مع
"name": " "و"tickets": 5←422، وتسمية الحقلين، وعدم حفظ أي شيء. - RF-05، سلبي، الخادم فقط: بريد مسجّل مسبقاً ← رسالة تحت حقل البريد، وبقاء بقية المدخلات.
- RF-06، إرسال مزدوج: نقر مزدوج على «تسجيل» مع شبكة مُبطَّأة ← سجل واحد وبريد واحد.
- RF-07، ملء تلقائي: هاتف محفوظ
+966501234567← يُخزَّن بالصيغة0501234567، أو يُرفض برسالة عن الصيغة؛ ويجب أن يحدد المتطلب أيهما.
أخطاء شائعة
- اختبار التحقق عبر النموذج فقط، دون التأكد أبداً من أن الخادم يفرض القواعد نفسها.
- الوثوق بالرسالة الظاهرة على الشاشة بدلاً من فحص الاستجابة والبيانات المخزّنة.
- الاكتفاء ببيانات اختبار مرتبة: لا فاصلة علوية، ولا نص عربي، ولا
+في البريد، ولا قيم ملصوقة. - التوقف عند أول رسالة في الإرسال الفارغ بدلاً من التحقق من الإبلاغ عن كل حقل ناقص.
- النقر على زر الإرسال مرة واحدة على اتصال سريع واستنتاج أن الإرسال المزدوج مستحيل.
- عدم تجربة الملء التلقائي أو مدير كلمات المرور أبداً، مع أن كثيراً من المستخدمين الحقيقيين يملؤون النماذج بهذه الطريقة.
من منظور ضمان الجودة
يبدأ اختبار النماذج في جلسة التنقيح (Refinement). اسأل عن كل حقل: ما قاعدته، ومن يفرضها (المتصفح أم الخادم أم كلاهما)، وما رسالته بالضبط، وماذا يحدث عند النجاح وعند الإخفاق وعند الإرسال الثاني. فالقواعد التي تعيش في ذهن المطور وحده تتحول إلى اختلافات بين الصفحة والخادم.
احتفظ بجدول للحقول بوصفه بيانات اختبار: صف لكل حقل فيه القيم الصالحة وغير الصالحة والطبقة التي تفحص كل قاعدة، ويغذّي لاحقاً الفحوص المؤتمتة. وفي تقرير الخطأ سمِّ الطبقة: «الصفحة ترفض + في البريد وواجهة API تقبله» يوجّه المطور إلى الشيفرة الصحيحة. ولا تتجاوز التحقق ولا تختبر الإرسال المزدوج إلا في بيئات مسموح لك باختبارها، وبحسابات اختبار.
تمرين عملي
خطّط لاختبارات نموذج طلب الدعم
في صفحة الدعم النموذج التالي. والمتطلب: «الاسم والبريد الإلكتروني إلزاميان. رقم الطلب اختياري، وإن أُدخل فهو ORD- ثم 6 أرقام. الرسالة إلزامية، من 20 إلى 1,000 حرف. ويمكن إرفاق لقطة شاشة واحدة بصيغة PNG أو JPG حتى 5 ميغابايت. وزر «إرسال» ينشئ تذكرة واحدة ويعرض رقمها». قارن الشيفرة بالمتطلب، ثم خطّط للاختبارات.
حين تكتمل قائمتك، قارنها بما يُخرجه مولّد اختبارات التحقق (Validation Test Generator).
<form action="/support" method="post">
<label for="name">Name *</label>
<input id="name" name="name" required>
<label for="email">Email *</label>
<input id="email" name="email" type="text" required>
<label for="order">Order number</label>
<input id="order" name="order" pattern="ORD-[0-9]{5}">
<label for="msg">Message *</label>
<textarea id="msg" name="message" minlength="20" maxlength="2000"></textarea>
<label for="shot">Screenshot</label>
<input id="shot" name="shot" type="file" accept=".png,.jpg,.pdf">
<button>Send</button>
</form>- اكتب الاختلافات بين الشيفرة والمتطلب.
- اكتب لكل حقل مدخلات إيجابية وسلبية، والطبقة التي يجب أن ترفض كل مدخل سلبي.
- أضف اختبارات رسائل الخطأ والإرسال المزدوج والملء التلقائي.
- اكتب أسئلتك لمالك المنتج.
إظهار الإجابة النموذجية
الاختلافات: حقل البريد type="text"، فلا يفحص المتصفح أي صيغة. ونمط pattern لرقم الطلب يطلب 5 أرقام لا 6. وحقل الرسالة بلا required، وmaxlength="2000" ضعف الحد. وتضيف accept الامتداد .pdf، وهي في كل الأحوال لا تفعل إلا تصفية نافذة اختيار الملف. وخارج المتطلب، لا توجد رموز autocomplete لحقلي الاسم والبريد. ولا تستطيع HTML تحديد حجم الملف، فحدّ 5 ميغابايت من مهمة الخادم على أي حال.
إيجابي: اسم فيه فاصلة علوية واسم عربي؛ وsara+help@example.com؛ ورقم طلب متروك فارغاً؛ وORD-123456 الذي يرفضه النمط الخاطئ حالياً، وهذا عيب؛ ورسالتان من 20 حرفاً ومن 1,000 حرف؛ وملف JPG وملف PNG حجمه 5 ميغابايت بالضبط. سلبي يرفضه المتصفح والخادم: اسم أو بريد فارغ، ورسالة من 19 حرفاً. ويرفضه الخادم وحده لأن هذه الصفحة تمرّره: sara@، وORD-12345، ورسالة فارغة، و20 مسافة، و1,001 حرف، وملف PDF، وصورة تزيد على 5 ميغابايت ببايت واحد، وملف نصي أُعيدت تسميته إلى .png.
وأيضاً: يظهر كل خطأ تحت حقله مع بقاء بقية المدخلات؛ وانقر «إرسال» نقراً مزدوجاً وأعد تحميل صفحة التأكيد مع شبكة مُبطَّأة، والمتوقع تذكرة واحدة؛ وبعد إضافة autocomplete="name" وautocomplete="email" يملأ الملء التلقائي الاسم والبريد.
الأسئلة: هل تُحذف المسافات حول القيم؟ كيف تُحسب الأحرف في النص العربي والرموز التعبيرية؟ هل تعني 5 ميغابايت 5,000,000 بايت أم 5,242,880 بايت، وهل يُعدّ ملف .jpeg من صيغة JPG؟ هل الرسالة نفسها المرسلة من تبويب ثانٍ تذكرة جديدة أم تكرار؟ ماذا يرى المستخدم عندما يفشل رفع الملف؟
أسئلة شائعة
إذا كان الخادم يفحص كل شيء، فلماذا أختبر التحقق من جهة العميل أصلاً؟
لأنه جزء من تجربة المستخدم. ففحوص جهة العميل تقدّم ملاحظات فورية ومحددة دون انتظار رد من الخادم. وإن كانت خاطئة فإنها تحجب مستخدمين صالحين قبل أن يُسأل الخادم أصلاً، أو تمرّر أخطاء إلى رسالة خادم أبطأ وأقل وضوحاً. لكل طبقة مهمتها، فاختبر الاثنتين.
هل تجاوز المتصفح اختبار أمان؟
إنه الفحص الوظيفي الأساسي للتأكد من أن الخادم يفرض قواعده بنفسه، وعلى كل مختبِر أن يجريه على الأنظمة المسموح له باختبارها. أما محاولة كسر الخادم عمداً، كإرسال حمولات الحقن، فهي اختبار أمان يأتي لاحقاً في خارطة الطريق ويتطلب إذناً مكتوباً.
كيف أختبر الملء التلقائي دون استخدام بياناتي الشخصية؟
أنشئ ملف تعريف منفصلاً للمتصفح واحفظ فيه بيانات اختبار: اسماً وهمياً، وبريداً على نطاق محجوز مثل example.com، ورقم هاتف للاختبار. ويُنتج مولّد المستخدمين الوهميين (Fake User Generator) ومولّد أرقام الهواتف الوهمية (Fake Phone Number Generator) مثل هذه البيانات. ولا تستخدم أبداً بياناتك الشخصية أو بيانات الدفع الحقيقية على نظام اختبار.
هل يمنع تعطيل زر الإرسال الإرسالَ المزدوج؟
جزئياً فقط. فهو يوقف النقرة الثانية في الصفحة نفسها، لكنه لا يوقف إعادة تحميل طلب POST، ولا النموذج نفسه في تبويب ثانٍ، ولا الطلب المُعاد إرساله. والحماية الموثوقة على الخادم، مثل فحص يرفض تسجيلاً ثانياً مطابقاً. فاختبر الاثنين.
المراجع
- HTML Living Standardلغة HTML، بما فيها مراجع المحارف المسماة (الكيانات) وقواعد التحليل التي تتبعها المتصفحات.
- OWASP Cheat Sheet Series: Input Validationالتحقق بقوائم السماح، والفرق بين الفحص النحوي والدلالي، ولماذا لا يُعدّ التحقق في المتصفح ضابطاً أمنياً أبداً.
- RFC 9110: HTTP Semanticsمعاني أساليب HTTP وحقول الترويسات ورموز الحالة والتفاوض على المحتوى، بغضّ النظر عن إصدار البروتوكول.
- Client-side form validation — MDNالتحقق من النماذج في المتصفح بالسمات المدمجة وبالسكربتات، ولماذا يساعد المستخدمين لكنه لا يغني أبداً عن التحقق في الخادم.
تدرّب بأدوات متقن
ولّد حالات اختبار للتحقق من حقول النماذج: الإلزامية والصيغة والطول والنطاق والنمط والقواعد المشتركة بين الحقول.
ولّد حالات اختبار سلبية لحقول النماذج وواجهات API: قيم فارغة وnull ونوع خاطئ وطول زائد وحقن وصيغة غير صالحة.
تحليل أمر cURL إلى الطريقة وعنوان URL والترويسات والمتن، ثم تحويله إلى fetch أو axios أو Python أو طلب منظّم.
أنشئ طلبات HTTP وأرسلها (الطريقة وعنوان URL والترويسات والمصادقة والجسم) وافحص الاستجابة — بديل خفيف لـ Postman داخل متصفحك.
ولّد سلاسل نصية اختبارية بترميز Unicode عبر الخطوط (العربية والديفاناغارية وCJK والسيريلية) والرموز التعبيرية وعلامات الدمج وصيغ التطبيع.
ولّد سجلات مستخدمين وهمية (الاسم واسم المستخدم والبريد الإلكتروني وكلمة المرور وبذرة الصورة الرمزية والدور) لحسابات الاختبار.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.