اختبار انتقال الحالات - شرح أكثر

مقال مجاني 14 دقيقة

مرحبا ويعطيكم العافية وأهلا وسهلا فيكم في درس جديد من دروس الاختبار! اليوم سنتحدث عن موضوع كثير مهم وعملي: اختبار انتقال الحالات.


مقدمة

خلينا نبلش بأمثلة من حياتنا اليومية:

إشارة المرور (Traffic Light):

  • تبدأ بـ أحمر ← بعدها أصفر ← بعدها أخضر ← وبعدها تعيد الكرة
  • لا تستطيع أن تروح مباشرة من أحمر لأخضر، صح؟
  • كل لون عبارة عن حالة (State)
  • الانتقال بينهم عبارة عن Transition

جهاز الصراف الآلي (ATM):

  • جاهز ← بتحط البطاقة ← تدخل الرمز ← تسحب مصاري ← تاخد البطاقة
  • كل خطوة عبارة عن حالة، والنظام يتذكر وين أنت

تليفونك:

  • مقفل (Locked) ← تفتحه ← مفتوح (Unlocked) ← تفعل مكالمة ← في اتصال (In Call) ← بتقفله
  • لو حاولت تعمل مكالمة والتليفون مقفل، لن يشتغل!

الفكرة الأساسية: الأنظمة الذكية تتذكر وين هي الآن، ونفس الحدث ممكن يعطي نتائج مختلفة حسب الحالة الحالية!


ما هو State Transition Testing؟

اختبار انتقال الحالات هو تقنية اختبار نستخدمها لفحص كيف النظام ينتقل من حالة لحالة بناءً على أحداث معينة.

نستخدم هذه التقنية للأنظمة التي عندها:

  • ذاكرة (تتذكر الحالة السابقة)
  • حالات مختلفة (States)
  • أحداث (Events) تسبب التغيير
  • سلوك مختلف حسب الحالة الحالية

المفاهيم الأساسية

1. الحالة (State)

الحالة = وضع النظام الحالي في لحظة معينة

أمثلة:

  • "مقفل" أو "مفتوح"
  • "جاهز" أو "قيد المعالجة" أو "تم الإرسال"
  • "Trial" أو "Active" أو "Cancelled"

2. الحدث (Event)

الحدث = شي يحدث يسبب تغيير الحالة

أمثلة:

  • "إدخال الباسورد"
  • "الضغط على زر الشراء"
  • "انتهاء الوقت (Timeout)"
  • "فشل الدفع"

3. الانتقال (Transition)

الانتقال = التحول من حالة لحالة ثانية

مثال:

  • من "سلة التسوق" ← إلى "قيد الدفع"

4. الإجراء (Action)

الإجراء = ماذا يصير أثناء الانتقال

أمثلة:

  • إرسال إيميل تأكيد
  • خصم المبلغ من الحساب
  • عرض رسالة خطأ

رسم الحالات - State Transition Diagram

منرسم مخطط بسيط:

  • الدوائر = الحالات (States)
  • الأسهم = الانتقالات (Transitions)
  • النص على الأسهم = الأحداث (Events)

مثال بسيط - مصباح (Lamp):

     [Turn On]
  ┌──────────────┐
  │              ▼
 OFF           ON
  ▲              │
  └──────────────┘
     [Turn Off]

مثال عملي #1: جهاز الصراف الآلي (ATM Machine)

خلينا ناخد مثال من الحياة الحقيقية - جهاز الصراف!

الحالات (States):

  1. Idle - جاهز، مستني البطاقة
  2. Card Inserted - البطاقة داخل الجهاز
  3. PIN Entry - الجهاز مستني رمز الدخول
  4. PIN Failed - الرمز غلط (محاولة أولى/ثانية)
  5. Authenticated - تم التحقق من الهوية
  6. Transaction - بيتم تنفيذ العملية
  7. Card Ejected - إخراج البطاقة
  8. Card Blocked - البطاقة محجوبة (بعد 3 محاولات فاشلة)

الأحداث (Events):

  • Insert Card (حط البطاقة)
  • Enter Correct PIN (رمز صحيح)
  • Enter Wrong PIN (رمز غلط)
  • Select Withdraw (اختر سحب مصاري)
  • Cancel (إلغاء)
  • Timeout (انتهى الوقت)
  • Take Card (خد البطاقة)

جدول الانتقالات:

الحالة الحالية الحدث الحالة الجديدة الإجراء
Idle Insert Card Card Inserted اطلب الرمز
Card Inserted Enter Correct PIN Authenticated أظهر القائمة
Card Inserted Enter Wrong PIN (1st) PIN Failed "محاولة 1 من 3"
PIN Failed (1st) Enter Wrong PIN PIN Failed (2nd) "محاولة 2 من 3"
PIN Failed (2nd) Enter Wrong PIN Card Blocked احجب البطاقة
Authenticated Select Withdraw Transaction نفذ السحب
Transaction Success Card Ejected اطلع البطاقة
Any State Timeout (60s) Card Ejected اطلع البطاقة

ملاحظة مهمة: نفس الحدث "Enter Wrong PIN" يعطي نتائج مختلفة حسب الحالة الحالية! هذه هي القوة الحقيقية لـ State Transition Testing.


مثال عملي #2: اشتراك Netflix

خلينا ناخد مثال كل الناس تعرفه - Netflix!

الحالات:

  1. No Account - لا يوجد حساب
  2. Trial - تجربة مجانية (30 يوم)
  3. Active - مشترك ودافع
  4. Paused - الاشتراك موقوف مؤقتاً
  5. Cancelled - الغى الاشتراك (لكن لسه شغال لنهاية الشهر)
  6. Expired - انتهى الاشتراك

الأحداث:

  • Sign Up (التسجيل)
  • Start Trial (بدء التجربة)
  • Subscribe (اشترك ودفع)
  • Pause (وقف مؤقت)
  • Resume (استئناف)
  • Cancel (إلغاء)
  • Payment Failed (فشل الدفع)
  • Renew (التجديد)
  • Trial Ended (انتهت التجربة)

الانتقالات المهمة:

No Account --[Sign Up + Start Trial]--> Trial
Trial --[Subscribe]--> Active
Trial --[Trial Ended, No Payment]--> Expired
Active --[Cancel]--> Cancelled
Active --[Payment Failed]--> Expired
Active --[Pause]--> Paused
Paused --[Resume]--> Active
Cancelled --[End of Billing Period]--> Expired
Expired --[Subscribe Again]--> Active
نصيحة
لاحظ إنه في "حالات مؤقتة" زي "Cancelled" - أنت ألغيت لكن لسه تستطيع أن تشوف لنهاية الشهر الذي دفعته!

مثال عملي #3: طلب أونلاين (E-commerce Order)

هسا نحكي عن شي كلنا نعمله - الطلب من Amazon أو أي موقع تسوق!

الحالات:

  1. Cart - السلة
  2. Checkout - صفحة الدفع
  3. Payment Processing - قيد معالجة الدفع
  4. Confirmed - تم التأكيد
  5. Preparing - قيد التجهيز
  6. Shipped - تم الشحن
  7. Out for Delivery - في الطريق إليك
  8. Delivered - تم التوصيل
  9. Returned - مرتجع
  10. Cancelled - ملغي
  11. Refunded - استرجاع المبلغ

الأحداث:

  • Add Item (أضف منتج)
  • Remove Item (احذف منتج)
  • Proceed to Checkout (اذهب للدفع)
  • Enter Payment (أدخل بيانات الدفع)
  • Payment Success (نجح الدفع)
  • Payment Failed (فشل الدفع)
  • Prepare Order (جهز الطلب)
  • Ship (أرسل)
  • Deliver (سلّم)
  • Return Request (طلب إرجاع)
  • Cancel Order (الغِ الطلب)
  • Refund (أرجع المبلغ)

جدول انتقالات مختصر:

الحالة الحالية الحدث الحالة الجديدة الإجراء
Cart Proceed to Checkout Checkout أظهر صفحة الدفع
Checkout Payment Success Confirmed أرسل إيميل تأكيد
Checkout Payment Failed Cart "فشل الدفع، حاول مرة ثانية"
Confirmed Cancel (within 1h) Cancelled ألغِ الطلب
Shipped Cancel Shipped "لا تستطيع أن تلغي، الطلب طلع!"
Delivered Return Request (14 days) Returned ابدأ عملية الإرجاع
Returned Refund Approved Refunded أرجع المبلغ

سؤال مهم للاختبار: ماذا يصير لو المستخدم حاول يلغي الطلب بعد أن انشحن؟ هذه انتقالة غير صالحة لازم نختبرها!


مثال عملي #4: تسجيل الدخول مع الحجب (Login with Lockout)

هذا المثال كثير مهم لأنه يوضح ليش الحالة (State) مهمة!

الحالات:

  1. Logged Out - مسجل خروج
  2. Attempt 1 Failed - محاولة أولى فاشلة
  3. Attempt 2 Failed - محاولة ثانية فاشلة
  4. Locked - الحساب محجوب (بعد 3 محاولات)
  5. Logged In - مسجل دخول

السيناريو:

User enters WRONG password
├─ If in state "Logged Out" ← Go to "Attempt 1 Failed"
├─ If in state "Attempt 1 Failed" ← Go to "Attempt 2 Failed"
└─ If in state "Attempt 2 Failed" ← Go to "LOCKED" (احجب الحساب!)

جدول الانتقالات:

الحالة الحالية الحدث الحالة الجديدة الإجراء
Logged Out Correct Password Logged In "مرحبا!"
Logged Out Wrong Password Attempt 1 Failed "خطأ في الباسورد"
Attempt 1 Failed Correct Password Logged In "مرحبا!"
Attempt 1 Failed Wrong Password Attempt 2 Failed "تحذير: محاولة 2 من 3"
Attempt 2 Failed Correct Password Logged In "مرحبا!"
Attempt 2 Failed Wrong Password Locked "حسابك محجوب لمدة 30 دقيقة"
Locked Any Password Locked "حسابك محجوب"
Locked 30 Minutes Passed Logged Out أعد تعيين العداد
Any State Logout Logged Out امسح السيشن

هذا المثال يوضح إنه نفس الحدث (Wrong Password) يعطي نتائج مختلفة حسب الحالة الحالية!


كيف نستخرج حالات الاختبار؟

عندنا مستويات مختلفة من التغطية (Coverage):

1. All States Coverage (0-switch)

اختبر كل حالة مرة واحدة على الأقل

مثال من ATM:

  • حالة اختبار تزور "Idle"
  • حالة اختبار تزور "Card Inserted"
  • حالة اختبار تزور "Authenticated"
  • إلخ...

هذه أضعف تغطية، لكن أحسن من لا شي!

2. All Transitions Coverage (1-switch)

اختبر كل انتقال مرة واحدة على الأقل

مثال من Login:

  • ✅ Test: Logged Out ← (Correct Password) ← Logged In
  • ✅ Test: Logged Out ← (Wrong Password) ← Attempt 1
  • ✅ Test: Attempt 1 ← (Wrong Password) ← Attempt 2
  • ✅ Test: Attempt 2 ← (Wrong Password) ← Locked

هذه تغطية قوية ومنطقية!

3. All Paths Coverage (N-switch)

اختبر كل مسار ممكن من البداية للنهاية

تحذير
هذه التغطية ممكن تكون مستحيلة لو عندك حلقات (loops) أو مسارات لا نهائية!

4. Invalid Transitions Testing

هذا الأهم! اختبر الانتقالات التي ما المفروض أن تصير!

أمثلة:

  • ❌ Ship order while still in "Cart" (اشحن طلب لسه في السلة!)
  • ❌ Withdraw money without entering PIN (اسحب مصاري بدون رمز!)
  • ❌ Cancel order after it's delivered (ألغِ طلب بعد أن وصل!)
  • ❌ Login while already logged in (سجل دخول وأنت مسجل!)

النظام المفروض يرفض هذه الطلبات أو يتعامل معها بشكل صحيح!


الانتقالات غير الصالحة (Invalid Transitions) - مهم جداً!

هذه هي الـ Gold Mine للباگات!

مثال من Amazon:

السيناريو الطبيعي:

Cart ← Checkout ← Payment ← Confirmed ← Shipped ← Delivered

السيناريوهات الخبيثة للاختبار:

  1. من Cart لـ Shipped مباشرة؟
  • افتح Developer Tools
  • غير الـ state في local storage
  • حاول توصل لصفحة "Shipped"
  • النظام المفروض أن يرجعك أو يعطيك خطأ!
  1. إلغاء بعد التوصيل:
  • طلب وصلك بالفعل
  • حاول تلغيه من الـ API مباشرة
  • ماذا سـيصير؟
  1. إرجاع بعد 6 شهور:
  • Amazon تسمح بالإرجاع لـ 30 يوم
  • حاول تعمل Return Request بعد 200 يوم
  • المفروض أن يرفض!

مثال من Instagram:

حالات البوست:

Draft ← Published ← Archived ← Deleted

اختبارات خبيثة:

  • حاول تعمل "Archive" لبوست في حالة "Draft" (ما نشرته أصلاً!)
  • حاول تعمل "Publish" لبوست في حالة "Deleted"
  • حاول تسترجع بوست بعد 60 يوم من الحذف

كل هذه الحالات لازم تنرفض، والنظام المفروض أن يتعامل معها بشكل آمن!


نصائح عملية للاختبار

1. ارسم المخطط أولاً!

قبل لا تبلش الاختبار، ارسم الـ State Transition Diagram على ورقة أو whiteboard. سيساعدك تشوف:

  • كل الحالات الممكنة
  • كل الانتقالات
  • المسارات المعقدة
  • الحالات "المنسية"

2. دور على الحلقات (Loops)

لو في حلقات لا نهائية، ستحتاج تحدد:

  • كم مرة ستكرر الحلقة في الاختبار؟
  • في شرط إيقاف؟
  • ممكن المستخدم يعلق في الحلقة؟

مثال: Netflix تسمحلك "Pause/Resume" كذا مرة - في حد أقصى؟

3. دور على الطرق المسدودة (Dead Ends)

في حالات لا تستطيع أن تطلع منها؟

مثال سيء:

Active ← Banned (permanently)

لو النظام حجب حسابك، لا يوجد طريقة ترجع؟ هذا dead end!

مثال أحسن:

Active ← Banned ← (Appeal) ← Under Review ← Active/Banned

4. اختبر زر "الرجوع" (Back Button)

كثير أنظمة تنكسر لو ضغطت Back في المتصفح!

مثال:

  1. سلة ← دفع ← نجح الدفع ← تأكيد
  2. اضغط Back في المتصفح
  3. اضغط "Confirm Payment" مرة ثانية
  4. هل سيشحن مرتين؟! 😱
تحذير
زر Back هو عدوك اللدود! اختبره دايماً في الأنظمة التي فيها states.

5. اختبر Timeout (انتهاء الوقت)

ماذا يصير لو المستخدم ترك الصفحة مفتوحة وراح شرب قهوة؟

أمثلة:

  • ATM: بعد 60 ثانية بدون حركة ← اطلع البطاقة
  • Booking.com: بعد 15 دقيقة بدون إكمال الحجز ← ألغِ الحجز
  • Payment page: بعد 10 دقائق ← Session expired

6. اختبر Refresh/Reload

ماذا يصير لو المستخدم عمل Refresh للصفحة؟

سيناريوهات:

  • Payment processing ← Refresh ← شحن مرتين؟
  • Form submission ← Refresh ← Submit مرتين؟
  • Checkout ← Refresh ← فقدان البيانات؟

الحل الصحيح: النظام لازم يحفظ الـ State في Session أو Database ويتعامل مع الـ Refresh بشكل صحيح!

7. اختبر التزامن (Concurrent Actions)

ماذا يصير لو المستخدم فتح نفس الصفحة في تابين مختلفين؟

مثال:

  • Tab 1: سلة فيها 3 منتجات
  • Tab 2: نفس السلة
  • Tab 1: احذف منتج
  • Tab 2: اضغط Checkout
  • ماذا سـيصير؟ السلة فيها 2 ولا 3 منتجات؟

متى نستخدم State Transition Testing؟

هذه التقنية مثالية لـ:

✅ أنظمة تسجيل الدخول/الخروج

  • Login/Logout flows
  • Password reset
  • Account lockout
  • Session management

✅ عربات التسوق والدفع

  • Shopping cart
  • Checkout process
  • Payment flow
  • Order tracking

✅ أنظمة الحجز

  • Booking.com (حجز فنادق)
  • Expedia (حجز طيران)
  • Calendly (حجز مواعيد)
  • Cinema ticket booking

✅ خدمات الاشتراك

  • Netflix, Spotify, YouTube Premium
  • Trial ← Subscription ← Cancellation
  • Pause/Resume features

✅ أنظمة سير العمل (Workflows)

  • Document approval (Draft ← Review ← Approved ← Published)
  • Leave request (Submitted ← Manager Review ← HR Review ← Approved)
  • Bug tracking (New ← Assigned ← In Progress ← Fixed ← Verified ← Closed)

✅ الألعاب

  • Player states (Idle ← Running ← Jumping ← Falling ← Dead)
  • Game modes (Menu ← Playing ← Paused ← Game Over)

✅ أجهزة IoT

  • Smart light (Off ← On ← Dimmed ← Color Mode)
  • Thermostat (Off ← Heating ← Cooling ← Auto)
  • Smart lock (Locked ← Unlocked ← Jammed)

❌ متى ما نستخدمها؟

  • Stateless APIs (كل request مستقل)
  • Simple forms (بدون workflow)
  • Static content pages

خلاصة الدرس

خلينا نلخص الأفكار الأساسية:

الأنظمة الذكية تتذكر وين هي الآن (الحالة الحالية)

نفس الحدث يعطي نتائج مختلفة حسب الحالة (Wrong password في محاولة أولى ≠ Wrong password في محاولة ثالثة)

State Transition Diagram = أداة قوية للتصور والتخطيط

اختبر الانتقالات الصالحة (Valid Transitions) - المسارات الطبيعية

اختبر الانتقالات غير الصالحة (Invalid Transitions) - هون تجد الباگات!

Back button, Refresh, Timeout = الأعداء الثلاثة التي لازم تختبرهم دايماً

ارسم قبل لا تختبر - المخطط يوضحلك حالات ما كنت ستفكر فيها

دور على Loops, Dead Ends, Missing Transitions - هذه مؤشرات على مشاكل في التصميم

✅ استخدم هذه التقنية للأنظمة التي فيها ذاكرة وسير عمل (Login, Shopping, Booking, Subscriptions)


تمرين عملي 🎯

هسا دورك! ارسم State Transition Diagram لـ منشور في Instagram:

الحالات الممكنة:

  • Draft (مسودة)
  • Published (منشور)
  • Archived (في الأرشيف)
  • Deleted (محذوف)

أسئلة للتفكير:

  1. ما هي الأحداث الذي تسبب الانتقال بين الحالات؟
  2. ما هي الانتقالات الصالحة؟
  3. ما هي الانتقالات غير الصالحة اللي لازم تختبرها؟
  4. هل تستطيع "تسترجع" بوست محذوف؟ لقديش؟
  5. ماذا يصير لو حذفت بوست وأنت offline، بعدها رجع الإنترنت؟

Extra Challenge:

أضف حالة جديدة: "Scheduled" (مجدول للنشر)

  • كيف رح يأثر هذا على المخطط؟
  • ما الأحداث الجديدة؟
  • ما الانتقالات الجديدة (الصالحة وغير الصالحة)؟

يعطيكم العافية، ونشوفكم في الدرس الجاي! 🚀