خليني أسألك سؤال:
لمّا تيجي تختبر Feature جديدة - مثلاً صفحة تسجيل حساب جديد (User Registration Form) - ما أول شي بتسويه؟
أكيد تذهب تملأ الحقول بطريقة صحيحة:
ahmed@example.comMyPassword123!MyPassword123!وبتدوس "تسجيل" - وترى إذا اشتغل!
هذا اسمه Positive Testing - اختبار الطريق السعيد!
لكن السؤال الأهم: هل هذا كافي؟
طبعاً لأ!
لأنه المستخدمين الحقيقيين مش دايم يعملوا الشيء الصحيح:
@123كل هذه الحالات - اسمها Negative Testing!
اليوم سنفهم بالتفصيل ما الفرق بينهم، ليش Negative Testing مهم جداً، وكيف تفكر فيه صح!
جاهزين؟ يلا نبدأ!
بنهاية هذا الدرس، ستكون قادراً على:
خلينا نشتغل على مثال حقيقي طول الدرس!
السيناريو: شركتك تبني موقع جديد - زي Souq.com أو أي موقع e-commerce.
وصلتك Story جديدة:
As a new user
I want to create an account
So that I can shop and track my ordersالشروط المطلوبة:
✅ User can register with: email, password, confirm password
✅ Email must be valid format (contains @)
✅ Password must be at least 8 characters
✅ Password and Confirm Password must match
✅ After successful registration, user is redirected to homepageبسيطة، صح؟
خليني نبدأ نختبرها - بالطريقتين!
Positive Testing = اختبار إنه الـ Feature تعمل صح لمّا المستخدم يعمل الشيء الصحيح!
يعني:
خلينا نكتب حالات إيجابية للـ Registration Form:
| الخطوة | البيانات | النتيجة المتوقعة |
|---|---|---|
| 1. افتح صفحة التسجيل | - | الصفحة تظهر بنجاح |
| 2. املأ البريد الإلكتروني | ahmed@example.com |
مقبول |
| 3. املأ كلمة السر | MyPassword123! |
مقبول |
| 4. املأ تأكيد كلمة السر | MyPassword123! |
مقبول |
| 5. اضغط "تسجيل" | - | ✅ التسجيل نجح، انتقال للصفحة الرئيسية |
النتيجة: ✅ PASS - المستخدم سجل بنجاح!
نفس الخطوات، لكن بنجرب أشكال مختلفة من البريد الإلكتروني الصحيح:
| البريد الإلكتروني | هل صحيح؟ |
|---|---|
user@example.com |
✅ صحيح - Standard |
user.name@example.com |
✅ صحيح - مع نقطة |
user+tag@example.com |
✅ صحيح - مع + |
user_123@example.co.uk |
✅ صحيح - subdomain |
كل هذه لازم تنجح!
| كلمة السر | هل صحيحة؟ |
|---|---|
MyPassword123! |
✅ 8 characters أو أكثر |
VeryStrongPassword2024@ |
✅ طويلة وقوية |
12345678 |
✅ 8 characters (لكن ضعيفة - سنحكي عنها بالـ Negative!) |
ملاحظة مهمة:
12345678تقنياً صحيحة لأنها 8 characters - فبالـ Positive Testing لازم تنجح!لكن هل هي كلمة سر آمنة؟ لأ! هذه مشكلة أخرى - سنحكي عنها!
اختبرنا الـ "Happy Path" - الطريق السعيد:
كل شي تمام! كل شي شغال!
هل هذا كافي؟
خليني أقولك قصة حقيقية:
سنة 2012، NASA:
كان عندهم موقع إلكتروني لبيع صور فضائية عالية الدقة - للعلماء والباحثين.
الصور كانت غالية جداً - بعضها بـ $10,000 للصورة الواحدة!
ما صار؟
في شخص ذكي - مش hacker حتى - لكن فاهم قليلاً تكنولوجيا - لاحظ شيء غريب:
لمّا يضيف صورة للسلة (Cart)، السعر كان بيجي من الـ Frontend مش من الـ Backend!
يعني:
{"item_id": 123, "price": 10000}ما عمل الشخص الذكي؟
فتح الـ Browser DevTools → راح على Network Tab → شاف الـ Request!
عدّل السعر من $10,000 لـ $1!
{
"item_id": 123,
"price": 1 // بدل 10000!
}ورسل الـ Request!
النتيجة: الـ Backend قبل السعر بدون فحص!
اشترى صور بملايين الدولارات بـ $1 للواحدة!
NASA اكتشفت الموضوع بعد فترة - لكن كان خسروا ملايين!
لأنه المختبرين اختبروا لكن الـ Positive Testing!
اختبروا:
لكن ما اختبروا:
Negative Testing = اختبار إنه الـ Feature تتصرف صح لمّا المستخدم يعمل الشيء الغلط!
يعني:
السبب بسيط:
معظم المستخدمين الحقيقيين مش بيتبعوا الشروط المكتوبة!
في 4 أنواع مستخدمين:
1. المستخدم المستعجل:
2. المستخدم الذي لا يعرف:
3. المستخدم الذي يجرب:
4. المستخدم الخبيث (Bad User / Hacker):
خلينا نكتب حالات سلبية للـ Registration Form - وشوف كم عددهم!
الفكرة: ما لو المستخدم ترك حقل فاضي؟
| الحالة | البيانات | النتيجة المتوقعة |
|---|---|---|
| TC-N-01 | Email: (فاضي) Password: MyPassword123! Confirm: MyPassword123! |
❌ Error: "البريد الإلكتروني مطلوب" |
| TC-N-02 | Email: user@example.com Password: (فاضي) Confirm: MyPassword123! |
❌ Error: "كلمة السر مطلوبة" |
| TC-N-03 | Email: user@example.com Password: MyPassword123! Confirm: (فاضي) |
❌ Error: "تأكيد كلمة السر مطلوب" |
| TC-N-04 | كل الحقول (فاضية) | ❌ Error: "يرجى ملء جميع الحقول" |
عددهم: 4 حالات سلبية - لكن من الحقول الفاضية!
الفكرة: ما لو المستخدم حط بريد إلكتروني غلط؟
| الحالة | البريد الإلكتروني | النتيجة المتوقعة |
|---|---|---|
| TC-N-05 | ahmed (بدون @) |
❌ Error: "صيغة البريد الإلكتروني غير صحيحة" |
| TC-N-06 | ahmed@ (@ لكن بدون domain) |
❌ Error |
| TC-N-07 | @example.com (domain لكن بدون username) |
❌ Error |
| TC-N-08 | ahmed @example.com (مسافة بالنص!) |
❌ Error |
| TC-N-09 | ahmed@@example.com (@ مكررة) |
❌ Error |
| TC-N-10 | ahmed@example (بدون.com) |
❌ Error أو تحذير |
| TC-N-11 | 12345 (رقم بس!) |
❌ Error |
| TC-N-12 | (رموز غريبة) !@#$%^&*() |
❌ Error |
عددهم: 8 حالات سلبية - لكن من البريد الإلكتروني!
الفكرة: ما لو المستخدم حط كلمة سر ضعيفة؟
ملاحظة: الشروط تقول "at least 8 characters" - لكن هل هذا كافي؟
| الحالة | كلمة السر | النتيجة المتوقعة |
|---|---|---|
| TC-N-13 | 123 (أقل من 8) |
❌ Error: "كلمة السر لازم تكون 8 أحرف على الأقل" |
| TC-N-14 | 1234567 (7 characters - أقل بواحد!) |
❌ Error |
| TC-N-15 | 12345678 (8 characters - لكن كلها أرقام!) |
سؤال: هل لازم ترفض؟ |
| TC-N-16 | aaaaaaaa (8 characters - لكن كلها نفس الحرف!) |
سؤال: هل لازم ترفض؟ |
| TC-N-17 | password (8 characters - لكن كلمة شائعة جداً!) |
سؤال: هل لازم ترفض؟ |
لا لازم يصير؟
في خيارين:
الخيار 1: نرفضها تماماً
❌ Error: "كلمة السر ضعيفة - لازم تحتوي على أحرف وأرقام ورموز"الخيار 2: نقبلها لكن نحذر المستخدم
⚠️ Warning: "كلمة السر ضعيفة - ننصح باستخدام كلمة سر أقوى"
(لكن نسمحله يكمل إذا يريد)| الحالة | Password | Confirm Password | النتيجة المتوقعة |
|---|---|---|---|
| TC-N-18 | MyPassword123! |
MyPassword456! (مختلفة تماماً) |
❌ Error: "كلمتا السر غير متطابقتين" |
| TC-N-19 | MyPassword123! |
MyPassword123 (بدون !) |
❌ Error |
| TC-N-20 | MyPassword123! |
mypassword123! (حرف صغير!) |
❌ Error |
ملاحظة: TC-N-20 مهمة جداً!
الفرق لكن حرف كبير/صغير - لكن لازم يكونوا متطابقين تماماً!
الفكرة: ما لو المستخدم حاول يسجل ببريد إلكتروني موجود مسبقاً؟
| الحالة | السيناريو | النتيجة المتوقعة |
|---|---|---|
| TC-N-21 | 1. سجل مستخدم ببريد user@example.com 2. حاول تسجل مرة ثانية بنفس البريد |
❌ Error: "البريد الإلكتروني مستخدم مسبقاً" |
ahmed@example.com
- النظام يقول: "البريد مستخدم مسبقاً"
- يعني Ahmed عنده حساب هون!
الحل الأفضل:
ℹ️ "إذا كان البريد الإلكتروني موجوداً، ستصلك رسالة تأكيد"
هيك لا تفضح إذا البريد موجود ولا لأ!
أنت كمختبر - لازم تعرف هذه الأمور وتختبرها!الفكرة: ما لو المستخدم حط نص طويل جداً؟
| الحالة | البيانات | النتيجة المتوقعة |
|---|---|---|
| TC-N-22 | Email: aaaaaaa...aaa@example.com (500 حرف) |
❌ Error: "البريد الإلكتروني طويل جداً" |
| TC-N-23 | Password: aaaaaaa... (10,000 حرف!) |
❌ Error أو يقبل لكن لحد limit معين |
ليش هذا مهم؟
1. مشاكل الـ Database:
2. مشاكل الأداء:
3. هجمات أمنية:
الفكرة: ما لو المستخدم حط رموز غريبة؟
| الحالة | البيانات | النتيجة المتوقعة |
|---|---|---|
| TC-N-24 | Email: <script>alert('hacked')</script>@example.com |
❌ Error - XSS Attack attempt! |
| TC-N-25 | Email: user' OR '1'='1'@example.com |
❌ Error - SQL Injection attempt! |
| TC-N-26 | Email: user@مثال.com (حروف عربية بالـ domain) |
✅ قد يكون صحيح! (IDN - Internationalized Domain Names) |
| TC-N-27 | Password: 😀🎉💻🚀 (Emoji!) |
سؤال: هل نقبلها؟ |
الفكرة: ما لو المستخدم حاول يسجل كذا مرة بسرعة؟
| الحالة | السيناريو | النتيجة المتوقعة |
|---|---|---|
| TC-N-28 | حاول تسجل 100 حساب بـ 1 دقيقة | Rate Limiting! ❌ "محاولات كثيرة، انتظر قليلاً" |
| TC-N-29 | دوس على زر "تسجيل" 10 مرات بسرعة | لازم يتجاهل الضغطات الزيادة! |
ليش هذا مهم؟
1. منع هجمات الـ Bot:
2. منع الـ Double Submission:
الفكرة: ما لو الإنترنت قُطع أثناء التسجيل؟
| الحالة | السيناريو | النتيجة المتوقعة |
|---|---|---|
| TC-N-30 | 1. املأ الحقول 2. اضغط "تسجيل" 3. قطّع الـ WiFi فوراً! |
❌ Error واضح: "مشكلة في الاتصال، يرجى المحاولة لاحقاً" |
| TC-N-31 | إنترنت بطيء جداً (Slow 3G) | ⏳ Loading Indicator + Timeout بعد وقت معقول |
ملاحظات:
TC-N-30: مش المفروض النظام يتجمد أو يطلع Error غريب!
لازم Error واضح ومفيد!
TC-N-31: لازم:
- Loading Indicator - المستخدم يعرف إنه في شي عم يصير
- Timeout - لو أخذ أكثر من 30 ثانية مثلاً - نوقف ونعطي Error
الفكرة: ما لو المستخدم عطّل JavaScript أو حذف Cookies؟
| الحالة | السيناريو | النتيجة المتوقعة |
|---|---|---|
| TC-N-32 | عطّل JavaScript في المتصفح | لازم يشتغل! (Server-side validation) |
| TC-N-33 | امسح Cookies بعد التسجيل | لازم Session يضل شغال (أو نطلب تسجيل دخول) |
javascript if (email.includes('@')) { // Email صحيح }
لكن ما لو المستخدم عطّل JavaScript؟
الـ Validation لن يشتغل!
الحل:
Server-Side Validation - لازم الـ Backend يفحص أيضاً!
لا تثق بالـ Frontend أبداً!عديناهم؟ خلينا نعد:
| الفئة | عدد الحالات |
|---|---|
| حقول فاضية | 4 |
| بريد إلكتروني غلط | 8 |
| كلمة سر ضعيفة | 5 |
| Password Mismatch | 3 |
| Duplicate Email | 1 |
| Input طويل جداً | 2 |
| Special Characters | 4 |
| Multiple Attempts | 2 |
| Network Issues | 2 |
| Browser Issues | 2 |
المجموع: 33 حالة سلبية!
مقابل كام حالة إيجابية؟ 3 حالات بس!
شايف الفرق؟
خليني أشاركك إحصائية حقيقية:
حسب دراسات متعددة في مجال Software Testing:
- 70-80% من الـ Bugs تنكشف في Negative Testing
- 20-30% لكن من الـ Bugs تنكشف في Positive Testing
ليش؟
لأنه المطورين - مثلنا كبشر - بيركزوا على "الطريق السعيد"!
لمّا المطور يكتب الكود، يفكر:
لكن الحقيقة مختلفة!
المستخدمين الحقيقيين:
وهون تصبح الـ Bugs!
خليني أعطيك نصيحة ذهبية:
ليش؟
1. الـ Positive Testing سهل:
2. الـ Negative Testing صعب:
3. الـ Negative Testing هو الذي يحمي النظام:
السؤال الكبير: كيف أطلع كل هذه الحالات السلبية؟
إليك 5 تقنيات عملية:
لكل شرط - فكر بالعكس!
مثال:
مثال 2:
لكل حد - اختبر:
مثال: Password length: minimum 8
| الحالة | القيمة |
|---|---|
| قبل الحد | 7 characters → ❌ |
| على الحد | 8 characters → ✅ |
| بعد الحد | 9 characters → ✅ |
سنشرح Boundary Value Analysis بالتفصيل في درس لاحق!
البس قبعة الـ Hacker!
اسأل نفسك:
أمثلة:
تخيل مستخدم:
ماذا يسوي؟
SFDPOT = اختصار لـ:
لكل واحد - فكر بحالات سلبية!
مثال:
Data:
Platform:
Time:
هسّا جاي دورك!
التحدي:
افتح Instagram (أو أي تطبيق بتحبه - Facebook, Twitter, LinkedIn).
روح على صفحة التسجيل (Signup Page).
مهمتك: طلّع 20 حالة سلبية!
Instagram Signup Form فيه:
حالات سلبية ممكنة:
1. Full Name:
2. Username:
3. Email/Phone:
4. Password:
5. Date of Birth:
6. سيناريوهات معقدة:
دورك كمختبر: تكتشف المشاكل قبل المستخدمين!
كل حالة سلبية - وثّقها!
ليش؟
مش كل الحالات السلبية نفس الأهمية!
High Priority:
Medium Priority:
Low Priority:
لا تختبر الـ Feature لحالها!
اختبر:
مثال: تسجيل حساب جديد:
كل هذه لازم تختبرها!
في أدوات تساعدك تكتشف حالات سلبية:
1. Fuzzing Tools:
2. Security Testing Tools:
3. Test Data Generators:
سنشرح هذه الأدوات بدروس لاحقة!
مستحيل!
الحالات السلبية لا نهائية تقريباً!
الحل:
لا تنسَ الحالات الشائعة!
مثال:
لأ!
Bug واحد ممكن يخبي وراه عشرات الـ Bugs!
مثال: لقيت إنه النظام لا يفحص Email format.
ما أيضاً مش عم يفحص؟
اليوم تعلمنا:
| Positive Testing | Negative Testing |
|---|---|
| اختبار الطريق السعيد | اختبار الطريق غير السعيد |
| بيانات صحيحة | بيانات غلط |
| نتوقع نجاح | نتوقع رفض أو Error |
| 20-30% من الـ Bugs | 70-80% من الـ Bugs |
✅ معظم الـ Bugs تختبئ بالسيناريوهات السلبية! ✅ المستخدمين الحقيقيين مش دايم يعملوا الصح ✅ في hackers يحاولوا يستغلوا الثغرات ✅ الحماية الحقيقية تأتي من Negative Testing
✅ فكر بالعكس (Inverse Thinking) ✅ فكر بالحدود (Boundary Thinking) ✅ فكر زي Bad User ✅ فكر زي مستخدم غلطان ✅ استخدم SFDPOT Heuristic
✅ 33 حالة سلبية للـ User Registration Form ✅ مقابل 3 حالات إيجابية بس!
شفت الفرق؟
عزيزي المختبر،
Negative Testing مش "اختبار إضافي" - هو الاختبار الحقيقي!
لأنه:
تذكر:
"المختبر الكويس مش ما يتأكد إنه الأشياء تعمل - المختبر الكويس هو الذي يتأكد إنه الأشياء لا تنكسر حتى لو المستخدم عمل كل شيء غلط!"
فخور بدورك! أنت خط الدفاع الأول!
مهمتك:
1. اختر تطبيق حقيقي:
2. اختر Feature:
3. طلّع 20 حالة سلبية:
4. نفذهم:
5. اكتب تقرير:
بالدرس الجاي:
سنتعلم تقنية جديدة اسمها Equivalence Partitioning - كيف نقسم الـ Input لمجموعات ونختبر بذكاء دون أن نختبر كل حالة ممكنة!
استعدوا - سيكون درس قوي!
إلى اللقاء!