WebSocket टेस्टिंग
WebSocket client और server के बीच एक लंबा चलने वाला, दो-तरफ़ा connection है, जिसे RFC 6455 परिभाषित करता है। यह connection upgrade माँगने वाली एक HTTP request से शुरू होता है; उसके बाद कोई भी पक्ष किसी भी पल message भेज सकता है, बिना request-response जोड़ों के। Chat, live tracking और trading screens इसे इसलिए इस्तेमाल करते हैं कि server बदलाव तुरंत push कर सके।
उदाहरण: एक delivery app order page पर एक connection खोलता है और order A-1042 को subscribe करता है। Order बदलने पर server {"type":"status","seq":2,"status":"picked_up"} push करता है और page बिना reload के update होता है। इसे टेस्ट करने का मतलब है जाँचना कि connection कैसे खुलता है, क्या और किस क्रम में आता है, वह कैसे बंद होता है, और टूटने पर या बहुत सारे clients के जुड़ने पर क्या होता है।
यह क्यों ज़रूरी है
हर message का कोई status code नहीं होता, इसलिए खोया हुआ, दोहराया गया या गलत क्रम में आया update कोई error नहीं देता: customer बस "delivered" के बाद "picked up" देखता है, या एक chat message दो बार। और क्योंकि connections घंटों खुले रहते हैं, कुछ failures quick check में कभी नहीं दिखतीं: idle connections काटने वाला proxy, connection के बीच में expire होता session, हर client के साथ बढ़ती server memory।
Tester का सवाल "यह request क्या लौटाती है?" से बदलकर हो जाता है "क्या पहुँचना चाहिए, किस क्रम में, कितने समय में, और drop के बाद क्या होता है?"
Opening handshake: HTTP से WebSocket तक
Client एक HTTP/1.1 GET भेजता है जिसमें Upgrade: websocket, Sec-WebSocket-Version: 13 और एक random Sec-WebSocket-Key होती है। Accept करने वाला server 101 Switching Protocols और उसी key से निकली Sec-WebSocket-Accept value लौटाता है; उसके बाद वही TCP connection WebSocket frames ले जाता है। Production में ws:// नहीं, TLS वाला wss:// होना चाहिए।
इस HTTP/1.1 handshake में कोई और status मतलब WebSocket खुला ही नहीं (HTTP/2 पर RFC 8441 इसकी जगह CONNECT request और 200 जवाब इस्तेमाल करता है), इसलिए access rules यहीं टेस्ट होते हैं। Cookies handshake के साथ जाती हैं, और RFC 6455 कहता है कि अगर Origin header ऐसी site बताए जिसे server स्वीकार नहीं करता, तो server को 403 लौटाना चाहिए। Browser scripts custom headers नहीं जोड़ सकतीं, इसलिए token अक्सर URL में जाता है, जहाँ वह logs में पहुँच सकता है। Script को rejected handshake का status कभी नहीं दिखता, सिर्फ़ close code 1006 वाला failed connection; असली status developer tools के Network panel में पढ़ें।
- Session नहीं, expired session या access नहीं:
101नहीं, बल्कि contract में लिखा401या403। - ऐसा origin जिसे server स्वीकार नहीं करता:
403। Browser हमेशा उस page का origin भेजता है जिसमें वह चल रहा है, इसलिए किसी दूसरी site से, जैसे WebSocket Tester से, connect करना पहले से ही foreign origin का test है; गायब या नकलीOriginके लिए browser के बाहर का client चाहिए। सिर्फ़ उन systems को टेस्ट करें जो आपके हैं या जिन्हें टेस्ट करने की आपको लिखित अनुमति है। - HTTPS पर served page जो
ws://खोले: browser इसे mixed content मानकर block करता है।
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=Messages, control frames और close codes
Data frames में चलता है। Message text (UTF-8) या binary होता है और कई frames में फैल सकता है। Ping control frame का जवाब pong से देना ज़रूरी है; browsers यह अपने-आप करते हैं पर दोनों को scripts से छिपाते हैं, इसलिए applications अक्सर अपना heartbeat message जोड़ती हैं। Built-in acknowledgements नहीं होते: अगर client को जानना है कि message process हुआ, तो application एक reply तय करती है, आम तौर पर id लौटाकर।
Messages को REST body की तरह टेस्ट करें: required fields, types, अनजाने message types, malformed JSON, और size limit व उससे एक byte ऊपर। कोई भी पक्ष close frame से connection खत्म करता है, जिसमें आम तौर पर code और optional reason होते हैं; दूसरा पक्ष अपने close frame से जवाब देता है। RFC 6455 के सबसे आम codes:
1000normal closure;1001going away, जैसे server का बंद होना या browser का page छोड़ना।1003ऐसा data type जिसे endpoint स्वीकार नहीं करता;1007message type से मेल न खाता data, जैसे text में invalid UTF-8;1008policy violation;1009message बहुत बड़ा;1011server में unexpected condition, यानी500का समकक्ष।1005और1006कभी close frame में भेजे नहीं जाते: endpoint खुद1005तब बताता है जब उसे मिले close frame में code न हो, और1006तब जब connection बिना close frame के खत्म हो, जैसे network drop, killed process या proxy timeout के बाद।- 4000 से 4999 तक के codes private use के लिए हैं: कोई API expired session के लिए
4401तय कर सकती है, और उसका मतलब वही है जो उस API का documentation कहता है।
- क्लाइंट Browser में order page
- सर्वर
wss://shop.example.test/live
- 1 क्लाइंट से सर्वर तक: Upgrade माँगने वाली HTTP GET
Sec-WebSocket-Keyऔर version 13 के साथ; session cookie भी साथ जाती हैUpgrade: websocket - 2 सर्वर से क्लाइंट तक: Handshake स्वीकार जवाब
Sec-WebSocket-Acceptkey से निकलती है; कोई और status मतलब WebSocket नहीं खुला101 Switching Protocols - 3 क्लाइंट से सर्वर तक: Order A-1042 को subscribe करता है
{"type":"subscribe","lastSeq":0} - 4 सर्वर से क्लाइंट तक: Subscription की पुष्टि करता है जवाब
{"type":"subscribed"} - 5 सर्वर से क्लाइंट तक: बिना माँगे update push करता है
{"seq":1,"status":"accepted"} - 6 सर्वर से क्लाइंट तक: कुछ न बदले तो heartbeat हर 20 s, ताकि कोई proxy चुप connection न काटे
{"type":"heartbeat"} - 7 सर्वर से क्लाइंट तक: अगला update, अगला sequence number
{"seq":2,"status":"picked_up"} - 8 क्लाइंट से सर्वर तक: User tracking बंद करता है: close frame App का भेजा normal closure; page छोड़ने पर browser 1001 भेजता है
1000 - 9 सर्वर से क्लाइंट तक: अपने close frame से जवाब, फिर TCP बंद जवाब
1000
परिणाम: Clean close: दोनों पक्षों ने close frame भेजा। Connection अचानक टूटता तो client 1006 बताता।
Ordering और reconnection की टेस्टिंग
एक connection पर frames उसी क्रम में पहुँचते हैं जिसमें भेजे गए; WebSocket TCP पर चलता है और कुछ भी उनका क्रम नहीं बदलता। Ordering defects application से आते हैं: कई server workers का publish करना, reconnect के बाद replay, client में asynchronous handling। हर message में sequence number test को जाँचने के लिए कुछ देता है।
Reconnection application का काम है। RFC 6455 सलाह देता है कि पहली कोशिश से पहले random delay हो और हर failure के बाद लंबा delay (back-off), ताकि हज़ारों clients recover हो रहे server पर एक साथ न टूट पड़ें। Reconnect के बाद client को फिर authenticate करना, फिर subscribe करना और छूटे messages पूरे करने होते हैं।
- क्लाइंट Browser में order page
- सर्वर
wss://shop.example.test/live
- 1 सर्वर से क्लाइंट तक: Update 1 आता है
{"seq":1,"status":"accepted"} - 2 क्लाइंट आंतरिक रूप से: Network drop: कोई close frame नहीं Client 1006 बताता है; इस बीच updates 2 और 3 होते हैं
1006 - 3 क्लाइंट आंतरिक रूप से: Random delay रुकता है, हर failure के बाद लंबा Back-off, जैसा RFC 6455 सलाह देता है
- 4 क्लाइंट से सर्वर तक: नया handshake Session cookie से फिर authenticate करता है
Upgrade: websocket - 5 सर्वर से क्लाइंट तक: स्वीकार जवाब
101 Switching Protocols - 6 क्लाइंट से सर्वर तक: मिले सबसे बड़े
seqके साथ फिर subscribe करता है{"type":"subscribe","lastSeq":1} - 7 सर्वर से क्लाइंट तक: सिर्फ़ छूटे updates replay करता है जवाब
{"seq":2,"status":"picked_up"} - 8 सर्वर से क्लाइंट तक: फिर अगला, क्रम से
{"seq":3,"status":"delivered"} - 9 क्लाइंट आंतरिक रूप से:
seqजाँचता है: न gap, न duplicate पास
परिणाम: Update 1 का दोहराना या update 2 का गायब होना defect है, भले page आख़िर में सही status दिखाए।
- Ordering: numbered messages की एक burst भेजें, और दो clients से एक साथ events; हर receiver को एक ही क्रम दिखे, बिना gaps या duplicates के।
- Drop: session के बीच network काटें (Wi-Fi बंद करें या proxy रोकें), events होने दें, फिर network लौटाएँ; हर छूटा update ठीक एक बार दिखे।
- Idle: proxy timeout से ज़्यादा देर चुप रहें; heartbeat connection खुला रखे, या client recover करे।
- Connected रहते session expire या access revoke हो: server private data भेजना बंद करे, और client अंतहीन reconnect की जगह user से sign in करवाए।
Load में WebSockets
यहाँ requests per second से ज़्यादा मायने रखते हैं एक साथ खुले connections, नए handshakes की दर, प्रति second deliver होते messages, और event से हर subscriber तक पहुँचने का delay। हर खुला connection server और हर proxy पर memory और एक socket रोकता है, चुप रहने पर भी। k6 और Gatling जैसे tools WebSocket clients script कर सकते हैं; load सिर्फ़ उन्हीं environments पर डालें जिनकी आपको अनुमति है।
- अपेक्षित peak connections तक ramp up करें और वहाँ टिके रहें, हर simulated client को असली users की तरह अपना test user और token देकर; failed handshakes और प्रति connection memory record करें।
- Fan-out: एक event हज़ारों subscribers तक; delivery latency median और 95th percentile (वह समय जिसके भीतर 95% deliveries पूरी होती हैं) पर report करें, एक ही machine की clock या synchronised clocks से नापकर।
- Reconnection storm: deployment की तरह सारे connections एक साथ गिराएँ; back-off reconnects को फैलाए और service recover हो।
- Slow consumers और soak (normal load पर लंबा run): धीरे पढ़ने वाला client server से बिना limit messages queue न करवाए, और घंटों में memory न बढ़े।
Worked example: live order tracking feed
Delivery app का contract: seq हर update पर एक बढ़ता है और status कभी पीछे नहीं जाता; कुछ न बदले तो हर 20 seconds में heartbeat आता है; reconnect के बाद client अपना lastSeq भेजता है और server सिर्फ़ बड़े seq वाले updates replay करता है; close codes हैं 1000 (user ने tracking बंद की), 1008 (invalid message) और 4401 (session expired, reconnect नहीं)। Sample में -> client से server और <- server से client है।
इससे निकली test conditions, हर एक frame log में दिखने वाली:
- दूसरे customer के order
B-2077को subscribe करने पर उसका कोई update न आए। Contract यह नहीं बताता कि server error message देगा या close code: यह test basis का gap है, जिसे पहले team के साथ तय करें। - बिना
orderIdका subscribe, या ऐसा text जो JSON नहीं है,1008से close हो;1011का मतलब है कि server गलत input पर fail हुआ। - एक मिनट तक कुछ न बदले तो लगभग हर 20 seconds में heartbeat आए और connection खुला रहे।
seq1 के बाद network काटें, order दो बार आगे बढ़ाएँ, network लौटाएँ: clientlastSeq1 के साथ फिर subscribe करे और 2 व 3 एक बार, क्रम से पाए।- Session expire होने पर client को
4401मिले, वह reconnect बंद करे और user से sign in करवाए।
-> {"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"}आम गलतियाँ
- सिर्फ़ एक tab में happy path टेस्ट करना; ज़्यादातर WebSocket defects drop, idle period या बहुत सारे connections के बाद दिखते हैं।
- भेजे गए message को पहुँचा हुआ मानना; acknowledgement के बिना drop से ठीक पहले भेजा गया message खो सकता है।
- Sequence numbers की जगह final screen जाँचना, जबकि gaps, duplicates और गलत क्रम sequence numbers ही दिखाते हैं।
- Authentication सिर्फ़ handshake पर टेस्ट करना, connection खुला रहते session expire होने पर नहीं।
- Automated tests में fixed waits; timeout के साथ अपेक्षित message का इंतज़ार करें, वरना tests धीमे और flaky बनते हैं।
QA का नज़रिया
Real-time features अक्सर एक वाक्य में आते हैं: "page live update होगा"। Refinement में message contract माँगें: message types और fields, sequence numbers, heartbeat interval, close codes और हर code पर client की प्रतिक्रिया, reconnect policy और छूटे messages कैसे वापस मिलते हैं। कुछ teams इसे AsyncAPI document में लिखती हैं; इसके बिना ordering और reconnection का कोई expected result नहीं होता।
Testing के दौरान timestamps वाला frame log रखें; WebSocket Tester उसे copy या download कर सकता है। Bug report में URL, steps, failure के आसपास के frames उनके sequence numbers के साथ, close code और close clean था या नहीं, लिखें। Load targets पहले run से पहले developers और operations के साथ तय करें।
अभ्यास
Chat session log में defects खोजें
एक support chat का contract: room के हर message पर seq 1 बढ़ता है; शांत room में हर 20 seconds पर {"type":"heartbeat"} आता है; drop के बाद client lastSeq के साथ फिर join करता है और server सिर्फ़ बड़े seq वाले messages replay करता है; close codes हैं 1000 (user ने room छोड़ा), 1008 (invalid message) और 4403 (room का access नहीं)।
नीचे के captured log को contract से मिलाएँ। लिखें कि log क्या साबित करता है, किसका सिर्फ़ संकेत देता है और क्या सही चला, हर finding के लिए एक follow-up test के साथ।
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."}- हर contract rule के लिए लिखें कि log में क्या जाँचा जा सकता है।
- Log पढ़ें: sequence numbers, समय के gaps, close code, rejoin और replay।
- सबूत को उस शक से अलग करें जिसके लिए server या proxy logs चाहिए।
- हर finding के लिए एक follow-up test लिखें।
मॉडल उत्तर दिखाएँ
साबित: एक ही connection पर seq 3, seq 2 से पहले आया, इसलिए customer order number पूछे जाने से पहले ही "I am checking your order" पढ़ता है। रास्ते में frames का क्रम नहीं बदलता, इसलिए server ने उन्हें ऐसे ही भेजा। Follow-up: agent से 50 तेज़ messages, फिर received seq list जाँचें।
साबित: 60 seconds की चुप्पी (10:00:09.460 से 10:01:09.470) बिना ज़रूरी heartbeat के। संकेत: 1006 मतलब कोई close frame नहीं, और ठीक 60 चुप seconds के बाद कटना proxy के idle timeout की ओर इशारा करता है; proxy logs से पुष्टि करें। Follow-up: एक शांत room 3 मिनट खुला रखें।
सही: client ने drop के लगभग आधे second बाद reconnect शुरू किया और lastSeq 3 के साथ फिर join किया, जो उसे मिला सबसे बड़ा seq है, न कि 2, जो आख़िर में पहुँचा था।
साबित: lastSeq 3 होने पर भी server ने seq 3 फिर भेजा, इसलिए client को वह दो बार मिला, और duplicates न हटाए तो वह उसे दो बार दिखाएगा। संभावित कारण: off-by-one, seq > lastSeq की जगह seq >= lastSeq। Follow-up: lastSeq 1 के साथ join करें और ठीक 2 और 3 की उम्मीद करें।
Cover नहीं: 1000, 1008 और 4403; room छोड़ने, invalid message और मना किए गए room के tests जोड़ें।
अक्सर पूछे जाने वाले सवाल
WebSocket testing, REST API testing से कैसे अलग है?
REST test एक request भेजकर एक response जाँचता है। WebSocket test खुले connection पर पूरी stream जाँचता है: कौन-से messages आते हैं, किस क्रम में और कितनी तेज़ी से, समय के साथ connection का क्या होता है, और वह कैसे खत्म होता है। REST की skills काम आती रहती हैं, जैसे contract से payload जाँचना, authentication और negative input, पर हर message का status code नहीं होता।
क्या browser developer tools काफ़ी हैं?
देखने के लिए हाँ: बड़े browsers का Network panel page का WebSocket connection और उसके messages दिखाता है। अपने messages भेजने, reconnect करने या log रखने के लिए WebSocket Tester जैसा client इस्तेमाल करें। Browser में चलने वाला client हमेशा अपने page का origin भेजता है और handshake में custom headers set नहीं कर सकता, इसलिए गायब या नकली Origin, या header में token, के test के लिए browser के बाहर का client चाहिए।
Close code 1006 का क्या मतलब है?
Connection बिना close frame के खत्म हुआ, इसलिए कोई code नहीं मिला। कोई भी पक्ष 1006 कभी नहीं भेजता; जिस पक्ष ने connection खत्म होते देखा, उसकी WebSocket library इसे खुद बताती है। आम कारण हैं network drop, crash या restart हुआ server process, या idle connections बंद करने वाला proxy; browser में server का rejected handshake भी 1006 पर खत्म होता है। Timing, Network panel और server व proxy logs जाँचें।
Load test में कितने connections खोलने चाहिए?
संख्या data पर रखें: production analytics या business forecast से एक साथ online users का peak, गुणा हर user के connections (अक्सर हर tab या device पर एक), साथ में team का तय किया margin। फिर उस level पर delivery latency और errors नापें, और वह level खोजें जहाँ target पूरा होना बंद हो जाता है।
संदर्भ
- RFC 6455: The WebSocket ProtocolHTTP पर WebSocket हैंडशेक, फ़्रेमिंग, मास्किंग, ping/pong और क्लोज़ कोड।
- The WebSocket API — MDNब्राउज़र का WebSocket API: कनेक्शन खोलना, मैसेज भेजना और क्लोज़ इवेंट संभालना।
- OWASP Web Security Testing Guide (WSTG)वेब एप्लिकेशन और API की सुरक्षा कमज़ोरियों को परखने की संदर्भ कार्यप्रणाली, एक-एक टेस्ट के रूप में।
Mutqan tools से अभ्यास करें
WebSocket सर्वर से कनेक्ट करें, मैसेज भेजें और आती हुई frames रीयल टाइम में देखें — सीधे अपने ब्राउज़र से।
JSON डॉक्यूमेंट को JSON Schema (draft-07 / 2019-09 / 2020-12 के मुख्य कीवर्ड) के विरुद्ध वैलिडेट करें।
अपने ब्राउज़र में ही JSON को तुरंत फ़ॉर्मेट, सुंदर और वैलिडेट करें, मनचाहे इंडेंटेशन के साथ।
k6, JMeter, Gatling और Locust लोड टेस्ट के लिए बड़े पैरामीटर डेटासेट (users, token, id, payload) बनाएँ।
और गहराई से
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।