اختبار WebSocket
يفتح بروتوكول WebSocket اتصالاً طويل العمر ثنائي الاتجاه بين العميل والخادم، وتعرّفه المواصفة RFC 6455. يبدأ الاتصال بطلب HTTP يطلب ترقية الاتصال (Upgrade)، وبعدها يستطيع أيّ من الطرفين إرسال رسالة في أي لحظة، دون أزواج الطلب والاستجابة. وتستخدمه تطبيقات الدردشة والتتبع المباشر وشاشات التداول ليدفع الخادم التغييرات فور حدوثها.
مثال: يفتح تطبيق توصيل اتصالاً واحداً في صفحة الطلب ويشترك في الطلب A-1042. وعندما يتغير الطلب يدفع الخادم {"type":"status","seq":2,"status":"picked_up"} فتتحدّث الصفحة دون إعادة تحميل. واختبار ذلك يعني فحص كيف يُفتح الاتصال، وما الذي يصل وبأي ترتيب، وكيف يُغلق، وماذا يحدث عندما ينقطع أو عندما يتصل عملاء كثيرون.
لماذا يهم
لا يوجد رمز حالة لكل رسالة، لذا لا يُطلق التحديث المفقود أو المكرر أو الخارج عن ترتيبه أي خطأ: يرى الزبون ببساطة «استلمه المندوب» بعد «تم التوصيل»، أو رسالة الدردشة نفسها مرتين. ولأن الاتصالات تبقى مفتوحة لساعات، فبعض الإخفاقات لا تظهر في فحص سريع: وكيل (Proxy) يقطع الاتصالات الخاملة، وجلسة تنتهي في منتصف الاتصال، وذاكرة خادم تنمو مع كل عميل.
ويتغيّر سؤال المختبِر من «ماذا يعيد هذا الطلب؟» إلى «ما الذي يجب أن يصل، وبأي ترتيب، وفي أي زمن، وماذا يحدث بعد الانقطاع؟».
مصافحة الافتتاح
يرسل العميل طلب GET من نوع HTTP/1.1 يحمل Upgrade: websocket وSec-WebSocket-Version: 13 ومفتاحاً عشوائياً في Sec-WebSocket-Key. والخادم الذي يقبل يجيب بـ 101 Switching Protocols مع قيمة Sec-WebSocket-Accept المشتقة من ذلك المفتاح، ومن بعدها يحمل اتصال TCP نفسه إطارات WebSocket (Frames). وينبغي أن تستخدم بيئة الإنتاج wss:// فوق TLS، لا ws://.
في مصافحة HTTP/1.1 هذه يعني أي رمز آخر أن اتصال WebSocket لم يُفتح (أما فوق HTTP/2 فتستخدم RFC 8441 طلب CONNECT يُجاب بالرمز 200)، لذا تُختبر قواعد الوصول هنا. فملفات تعريف الارتباط (Cookies) تنتقل مع المصافحة، وتنص RFC 6455 على أن الخادم ينبغي أن يجيب بـ 403 إذا أشارت ترويسة Origin إلى موقع لا يقبله. ولا تستطيع سكربتات المتصفح إضافة ترويسات مخصصة، لذا ينتقل رمز الوصول (Token) غالباً في عنوان URL، فقد ينتهي به المطاف في السجلات. ولا يرى السكربت أبداً رمز الحالة لمصافحة مرفوضة، بل اتصالاً فاشلاً برمز الإغلاق 1006؛ فاقرأ الرمز الحقيقي في لوحة الشبكة (Network) ضمن أدوات المطور.
- دون جلسة، أو بجلسة منتهية، أو دون صلاحية: لا
101، بل401أو403كما يحدد العقد. - أصل (Origin) لا يقبله الخادم:
403. يرسل المتصفح دائماً أصل الصفحة التي يعمل فيها، لذا فالاتصال من موقع آخر، مثل أداة WebSocket Tester، يختبر بالفعل أصلاً خارجياً؛ أما ترويسةOriginغائبة أو مزوّرة فتحتاج إلى عميل خارج المتصفح. ولا تختبر إلا أنظمة تملكها أو لديك إذن مكتوب باختبارها. - صفحة تُخدَّم عبر HTTPS وتفتح
ws://: يحظرها المتصفح بوصفها محتوى مختلطاً (Mixed Content).
GET /live HTTP/1.1
Host: shop.example.test
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://shop.example.test
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=الرسائل وإطارات التحكم ورموز الإغلاق
تنتقل البيانات في إطارات. والرسالة نصية (UTF-8) أو ثنائية (Binary) وقد تمتد على عدة إطارات. وإطار التحكم ping يجب أن يُجاب بإطار pong؛ والمتصفح يفعل ذلك تلقائياً لكنه يخفي الإطارين عن السكربتات، لذا تضيف التطبيقات غالباً رسالة نبض (Heartbeat) خاصة بها. ولا توجد إقرارات استلام (Acknowledgements) مدمجة: فإذا احتاج العميل إلى معرفة أن رسالته عولجت، يعرّف التطبيق رداً يعيد عادةً معرّف id.
اختبر الرسائل كما تختبر جسم طلب REST: الحقول الإلزامية والأنواع وأنواع الرسائل غير المعروفة وJSON التالف، وحدّ الحجم وبايتاً واحداً فوقه. وينهي أيّ من الطرفين الاتصال بإطار إغلاق (Close Frame) يحمل عادةً رمزاً وسبباً اختيارياً، فيرد الطرف الآخر بإطار إغلاق خاص به. وأكثر رموز RFC 6455 ظهوراً:
1000إغلاق طبيعي؛1001مغادرة (Going Away)، كخادم يتوقف عن العمل أو متصفح يغادر الصفحة.1003نوع بيانات لا تقبله نقطة النهاية؛1007بيانات لا تناسب نوع الرسالة، مثل UTF-8 غير صالح في نص؛1008مخالفة سياسة؛1009رسالة أكبر من المسموح؛1011حالة غير متوقعة في الخادم، وهو نظير500.1005و1006لا يُرسلان أبداً في إطار إغلاق: يبلّغ الطرف نفسه عن1005إذا وصله إطار إغلاق بلا رمز، وعن1006إذا انتهى الاتصال دون إطار إغلاق، بعد انقطاع الشبكة أو إيقاف العملية قسراً أو انتهاء مهلة الوكيل.- الرموز من 4000 إلى 4999 للاستخدام الخاص: قد تعرّف واجهة ما
4401لجلسة منتهية، ولا يعني إلا ما يقوله توثيق تلك الواجهة.
- العميل صفحة الطلب في المتصفح
- الخادم
wss://shop.example.test/live
- 1 من العميل إلى الخادم: طلب HTTP GET يطلب الترقية مع
Sec-WebSocket-Keyوالإصدار 13؛ ويُرسل ملف تعريف ارتباط الجلسة معهUpgrade: websocket - 2 من الخادم إلى العميل: قُبلت المصافحة ردّ قيمة
Sec-WebSocket-Acceptمشتقة من المفتاح؛ وأي رمز آخر يعني أنه لا اتصال WebSocket101 Switching Protocols - 3 من العميل إلى الخادم: يشترك في الطلب A-1042
{"type":"subscribe","lastSeq":0} - 4 من الخادم إلى العميل: يؤكد الاشتراك ردّ
{"type":"subscribed"} - 5 من الخادم إلى العميل: يدفع تحديثاً دون أن يطلبه أحد
{"seq":1,"status":"accepted"} - 6 من الخادم إلى العميل: رسالة نبض ما دام لا شيء يتغير كل 20 ثانية، كي لا يقطع أي وكيل اتصالاً صامتاً
{"type":"heartbeat"} - 7 من الخادم إلى العميل: التحديث التالي برقم تسلسلي تالٍ
{"seq":2,"status":"picked_up"} - 8 من العميل إلى الخادم: يغلق المستخدم شاشة التتبع: إطار إغلاق إغلاق طبيعي يرسله التطبيق؛ أما مغادرة الصفحة فتجعل المتصفح يرسل 1001
1000 - 9 من الخادم إلى العميل: يرد بإطار إغلاق خاص به، ثم يُغلق اتصال TCP ردّ
1000
النتيجة: إغلاق نظيف: أرسل الطرفان إطار إغلاق. ولو انقطع الاتصال فجأة لأبلغ العميل عن 1006.
اختبار الترتيب وإعادة الاتصال
تصل الإطارات على الاتصال الواحد بالترتيب الذي أُرسلت به، فبروتوكول WebSocket يعمل فوق TCP ولا شيء يعيد ترتيبها. أما عيوب الترتيب فمصدرها التطبيق: عدة عمليات عاملة (Workers) في الخادم تنشر الرسائل، أو إعادة إرسال بعد إعادة الاتصال، أو معالجة غير متزامنة في العميل. والرقم التسلسلي (Sequence Number) في كل رسالة يعطي الاختبار ما يفحصه.
وإعادة الاتصال مسؤولية التطبيق. وتوصي RFC 6455 بتأخير عشوائي قبل المحاولة الأولى وتأخيرات أطول بعد كل فشل (التراجع أو Back-off)، كي لا يندفع آلاف العملاء إلى خادم يتعافى في اللحظة نفسها. وبعد إعادة الاتصال يجب أن يصادق العميل من جديد، ويعيد اشتراكه، ويلحق بما فاته.
- العميل صفحة الطلب في المتصفح
- الخادم
wss://shop.example.test/live
- 1 من الخادم إلى العميل: يصل التحديث 1
{"seq":1,"status":"accepted"} - 2 العميل داخليًا: تنقطع الشبكة: لا إطار إغلاق يبلّغ العميل عن 1006؛ ويقع التحديثان 2 و3 في هذه الأثناء
1006 - 3 العميل داخليًا: ينتظر تأخيراً عشوائياً يطول بعد كل فشل التراجع، كما توصي RFC 6455
- 4 من العميل إلى الخادم: مصافحة جديدة يصادق من جديد بملف تعريف ارتباط الجلسة
Upgrade: websocket - 5 من الخادم إلى العميل: قُبلت ردّ
101 Switching Protocols - 6 من العميل إلى الخادم: يعيد الاشتراك بأعلى
seqاستلمه{"type":"subscribe","lastSeq":1} - 7 من الخادم إلى العميل: يعيد إرسال الفائت فقط ردّ
{"seq":2,"status":"picked_up"} - 8 من الخادم إلى العميل: ثم التالي، بالترتيب
{"seq":3,"status":"delivered"} - 9 العميل داخليًا: يفحص
seq: لا فجوة ولا تكرار نجاح
النتيجة: تكرار التحديث 1 أو غياب التحديث 2 عيب حتى لو انتهت الصفحة إلى الحالة الصحيحة.
- الترتيب: أرسل دفعة من الرسائل المرقّمة، وأحداثاً من عميلين في وقت واحد؛ يرى كل مستقبِل الترتيب نفسه دون فجوات أو تكرار.
- الانقطاع: اقطع الشبكة في منتصف الجلسة (أطفئ Wi-Fi أو أوقف الوكيل)، ودع أحداثاً تقع، ثم أعدها؛ يظهر كل تحديث فائت مرة واحدة بالضبط.
- الخمول: ابقَ صامتاً مدة أطول من مهلة الوكيل؛ فإما أن تبقي رسائل النبض الاتصال مفتوحاً، وإما أن يتعافى العميل.
- انتهاء الجلسة أو سحب الصلاحية أثناء الاتصال: يتوقف الخادم عن إرسال البيانات الخاصة، ويطلب العميل من المستخدم تسجيل الدخول بدلاً من إعادة الاتصال إلى ما لا نهاية.
WebSocket تحت الحمل
عدد الطلبات في الثانية أقل أهمية هنا من عدد الاتصالات المفتوحة معاً، ومعدل المصافحات الجديدة، والرسائل المسلَّمة في الثانية، والتأخير بين وقوع الحدث ووصوله إلى كل مشترك. وكل اتصال مفتوح يحجز ذاكرة ومقبساً (Socket) على الخادم وعلى كل وكيل، حتى وهو صامت. وأدوات مثل k6 وGatling تتيح كتابة سكربتات تحاكي عملاء WebSocket؛ ولا تُجرِ اختبار الحمل إلا على البيئات المسموح لك باختبارها.
- صعّد إلى ذروة الاتصالات المتوقعة وحافظ عليها، مع مستخدم اختباري ورمز وصول خاصّين بكل عميل محاكى كما لدى المستخدمين الحقيقيين؛ وسجّل المصافحات الفاشلة والذاكرة لكل اتصال.
- التوزيع (Fan-out): حدث واحد إلى آلاف المشتركين؛ أبلغ عن زمن التسليم عند الوسيط (Median) وعند المئين 95 (الزمن الذي تبقى ضمنه 95٪ من عمليات التسليم)، مقيساً بساعة جهاز واحد أو بساعات متزامنة.
- عاصفة إعادة الاتصال: أسقط كل الاتصالات معاً كما يفعل النشر (Deployment)؛ وينبغي أن يوزّع التراجع المحاولات وأن تتعافى الخدمة.
- المستهلكون البطيئون والتحمّل الطويل (Soak)، أي تشغيل طويل تحت حمل عادي: العميل البطيء في القراءة يجب ألا يجعل الخادم يكدّس الرسائل بلا حد، والذاكرة يجب ألا تنمو على مدى ساعات.
مثال تطبيقي: تتبّع الطلب المباشر
عقد تطبيق التوصيل: يزيد seq بمقدار واحد مع كل تحديث ولا تعود الحالة إلى الوراء أبداً؛ وتصل رسالة نبض كل 20 ثانية عندما لا يتغير شيء؛ وبعد إعادة الاتصال يرسل العميل lastSeq فلا يعيد الخادم إلا التحديثات ذات seq الأعلى؛ ورموز الإغلاق 1000 (أغلق المستخدم شاشة التتبع) و1008 (رسالة غير صالحة) و4401 (انتهت الجلسة، فلا إعادة اتصال). وفي العينة يعني -> من العميل إلى الخادم، و<- من الخادم إلى العميل.
وهذه شروط الاختبار المستخرجة منه، ولكل منها نتيجة ظاهرة في سجل الإطارات:
- الاشتراك في طلب زبون آخر
B-2077لا يوصل أيّاً من تحديثاته. ولا يحدد العقد هل يجيب الخادم برسالة خطأ أم برمز إغلاق: وهذه فجوة في أساس الاختبار تُحسم مع الفريق أولاً. - اشتراك بلا
orderId، أو نص ليس JSON، يُغلق بالرمز1008؛ أما1011فيعني أن الخادم تعطّل بسبب مدخل خاطئ. - إذا لم يتغير شيء مدة دقيقة، تصل رسالة نبض كل 20 ثانية تقريباً ويبقى الاتصال مفتوحاً.
- اقطع الشبكة بعد
seq1، وقدّم حالة الطلب خطوتين، ثم أعد الشبكة: يعيد العميل الاشتراك معlastSeq1 ويستلم 2 و3 مرة واحدة وبالترتيب. - عند انتهاء الجلسة يستلم العميل
4401، فيتوقف عن إعادة الاتصال ويطلب من المستخدم تسجيل الدخول.
-> {"type":"subscribe","orderId":"A-1042","lastSeq":0}
<- {"type":"subscribed","orderId":"A-1042"}
<- {"type":"status","orderId":"A-1042","seq":1,"status":"accepted"}
<- {"type":"heartbeat"}
<- {"type":"status","orderId":"A-1042","seq":2,"status":"picked_up"}
<- {"type":"status","orderId":"A-1042","seq":3,"status":"delivered"}أخطاء شائعة
- اختبار المسار السعيد فقط في تبويب واحد؛ فمعظم عيوب WebSocket تظهر بعد انقطاع أو فترة خمول أو تحت اتصالات كثيرة.
- اعتبار الرسالة المرسلة رسالة مستلمة؛ فدون إقرار استلام قد تضيع رسالة أُرسلت قبيل الانقطاع.
- فحص الشاشة النهائية بدلاً من الأرقام التسلسلية التي تكشف الفجوات والتكرار واختلال الترتيب.
- اختبار المصادقة عند المصافحة فقط، وليس عند انتهاء الجلسة والاتصال ما زال مفتوحاً.
- استخدام انتظار ثابت في الاختبارات المؤتمتة؛ انتظر الرسالة المتوقعة مع مهلة قصوى، وإلا صارت الاختبارات بطيئة وغير مستقرة (Flaky).
من منظور ضمان الجودة
كثيراً ما تأتي الميزات اللحظية بجملة واحدة: «تتحدّث الصفحة مباشرة». فاطلب في جلسات تحسين المتطلبات (Refinement) عقد الرسائل: أنواع الرسائل وحقولها، والأرقام التسلسلية، وفترة النبض، ورموز الإغلاق وردّ العميل على كل منها، وسياسة إعادة الاتصال وطريقة استعادة الرسائل الفائتة. بعض الفرق تكتبه في مستند AsyncAPI؛ ودونه لا توجد نتيجة متوقعة للترتيب ولا لإعادة الاتصال.
احتفظ أثناء الاختبار بسجل للإطارات مع توقيت كل منها، وأداة WebSocket Tester تنسخ السجل أو تنزّله. ويذكر تقرير الخطأ العنوان والخطوات والإطارات المحيطة بالإخفاق مع أرقامها التسلسلية ورمز الإغلاق وهل كان الإغلاق نظيفاً. واتفق على أهداف الحمل مع المطورين وفريق العمليات قبل أول تشغيل.
تمرين عملي
اكتشف العيوب في سجل جلسة دردشة
عقد دردشة دعم فني: يزيد seq بمقدار 1 مع كل رسالة في الغرفة؛ وتستلم الغرفة الهادئة {"type":"heartbeat"} كل 20 ثانية؛ وبعد الانقطاع ينضم العميل من جديد مع lastSeq ولا يعيد الخادم إلا الرسائل ذات seq الأعلى؛ ورموز الإغلاق 1000 (غادر المستخدم الغرفة) و1008 (رسالة غير صالحة) و4403 (لا صلاحية لدخول الغرفة).
قارن السجل الملتقط أدناه بالعقد. اذكر ما يثبته السجل، وما يوحي به فقط، وما عمل بشكل صحيح، مع اختبار متابعة واحد لكل نتيجة.
10:00:00.120 info Connected wss://chat.example.test/ws
10:00:00.180 sent {"type":"join","room":"support-17","lastSeq":0}
10:00:00.250 recv {"type":"joined","room":"support-17"}
10:00:04.010 recv {"type":"msg","seq":1,"text":"Hello, how can I help?"}
10:00:09.400 recv {"type":"msg","seq":3,"text":"I am checking your order."}
10:00:09.460 recv {"type":"msg","seq":2,"text":"Please share the order number."}
10:01:09.470 info Closed: code 1006, clean: false
10:01:09.980 info Reconnecting (attempt 1)
10:01:10.150 info Connected wss://chat.example.test/ws
10:01:10.200 sent {"type":"join","room":"support-17","lastSeq":3}
10:01:10.270 recv {"type":"joined","room":"support-17"}
10:01:10.300 recv {"type":"msg","seq":3,"text":"I am checking your order."}- دوّن ما تسمح لك كل قاعدة في العقد بفحصه في السجل.
- تتبّع السجل سطراً سطراً: الأرقام التسلسلية، والفجوات الزمنية، ورمز الإغلاق، وإعادة الانضمام، وإعادة الإرسال.
- افصل الإثبات عن الشك الذي يحتاج إلى سجلات الخادم أو الوكيل.
- اكتب اختبار متابعة لكل نتيجة.
إظهار الإجابة النموذجية
مُثبَت: وصل seq 3 قبل seq 2 على اتصال واحد، فيقرأ الزبون «أتحقق من طلبك» قبل أن يُطلب منه رقم الطلب. والإطارات لا يُعاد ترتيبها في الطريق، إذن أرسلها الخادم هكذا. المتابعة: 50 رسالة سريعة من موظف الدعم، ثم فحص قائمة seq المستلمة.
مُثبَت: 60 ثانية من الصمت (من 10:00:09.460 إلى 10:01:09.470) دون رسالة النبض المطلوبة. ومُرجَّح: الرمز 1006 يعني أنه لا إطار إغلاق، والانقطاع بعد 60 ثانية صامتة بالضبط يشير إلى مهلة خمول في الوكيل؛ فأكّد ذلك من سجلات الوكيل. المتابعة: اترك غرفة هادئة مفتوحة 3 دقائق.
صحيح: بدأ العميل إعادة الاتصال بعد نحو نصف ثانية من الانقطاع، وانضم من جديد مع lastSeq 3، أي أعلى seq استلمه، لا 2 الذي وصل أخيراً.
مُثبَت: أعاد الخادم إرسال seq 3 مع أن lastSeq كان 3، فاستلم العميل الرسالة مرتين، وسيعرضها مرتين ما لم يُسقط المكرر. والسبب المرجَّح: خطأ الإزاحة بواحد (Off-by-one)، أي seq >= lastSeq بدلاً من seq > lastSeq. المتابعة: انضم مع lastSeq 1 وتوقّع 2 و3 بالضبط.
لا يغطيها السجل: 1000 و1008 و4403؛ فأضف اختبارات للمغادرة وللرسالة غير الصالحة وللغرفة الممنوعة.
أسئلة شائعة
ما الفرق بين اختبار WebSocket واختبار واجهة REST؟
اختبار REST يرسل طلباً ويفحص استجابة واحدة. أما اختبار WebSocket فيفحص تدفقاً على اتصال مفتوح: أيّ الرسائل تصل، وبأي ترتيب وسرعة، وماذا يحدث للاتصال مع الوقت، وكيف ينتهي. وتبقى مهارات REST مفيدة، مثل فحص الحمولة مقابل العقد والمصادقة والمدخلات السلبية، لكن لا يوجد رمز حالة لكل رسالة.
هل تكفي أدوات المطور في المتصفح؟
تكفي للمراقبة: فلوحة الشبكة (Network) في المتصفحات الرئيسية تعرض اتصال WebSocket الخاص بالصفحة ورسائله. ولإرسال رسائلك أو إعادة الاتصال أو حفظ سجل استخدم عميلاً مثل أداة WebSocket Tester. والعميل الذي يعمل في المتصفح يرسل دائماً أصل صفحته ولا يستطيع ضبط ترويسات مخصصة للمصافحة، لذا يحتاج اختبار ترويسة Origin غائبة أو مزوّرة، أو رمز وصول في ترويسة، إلى عميل خارج المتصفح.
ماذا يعني رمز الإغلاق 1006؟
يعني أن الاتصال انتهى دون إطار إغلاق، فلم يُستلم أي رمز. ولا يرسل أي طرف الرمز 1006 أبداً، بل تضعه مكتبة WebSocket لدى الطرف الذي رأى الاتصال ينتهي. ومن أسبابه الشائعة انقطاع الشبكة، أو تعطّل عملية الخادم أو إعادة تشغيلها، أو وكيل يغلق الاتصالات الخاملة؛ وفي المتصفح تنتهي المصافحة التي رفضها الخادم بالرمز 1006 أيضاً. فافحص التوقيت ولوحة الشبكة وسجلات الخادم والوكيل.
كم اتصالاً يجب أن يفتح اختبار الحمل؟
ابنِ الرقم على بيانات: ذروة المستخدمين المتصلين معاً من تحليلات الإنتاج أو توقعات العمل، مضروبة في عدد الاتصالات لكل مستخدم (غالباً اتصال لكل تبويب أو جهاز)، مع هامش يتفق عليه الفريق. ثم قِس زمن التسليم والأخطاء عند هذا المستوى، وابحث عن المستوى الذي يتوقف عنده تحقيق الهدف.
المراجع
- RFC 6455: The WebSocket Protocolمصافحة WebSocket عبر HTTP والتأطير والإخفاء وping/pong ورموز الإغلاق.
- The WebSocket API — MDNواجهة WebSocket في المتصفح: فتح الاتصال وإرسال الرسائل ومعالجة أحداث الإغلاق.
- OWASP Web Security Testing Guide (WSTG)المنهجية المرجعية لاختبار تطبيقات الويب وواجهات API بحثاً عن نقاط الضعف الأمنية، اختباراً تلو الآخر.
تدرّب بأدوات متقن
اتصل بخوادم WebSocket، وأرسل الرسائل، وراقب الإطارات الواردة في الوقت الفعلي — مباشرةً من متصفحك.
التحقق من مستند JSON مقابل مخطط JSON Schema (الكلمات المفتاحية الأساسية في draft-07 / 2019-09 / 2020-12).
تنسيق JSON وتجميله والتحقق من صحته فوراً في متصفحك مع مسافة بادئة قابلة للتخصيص.
ولّد مجموعات معاملات كبيرة (مستخدمين ورموزاً ومعرّفات وحمولات) لاختبارات التحميل في k6 وJMeter وGatling وLocust.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.