टेस्टर्स के लिए JavaScript बेसिक्स
JavaScript वह programming language है जिसे browser web pages के अंदर चलाता है। HTML पेज को structure देता है, CSS उसका रूप और JavaScript उसका behaviour। जब आप "Add to cart" पर click करते हैं और reload के बिना cart का badge 2 से 3 हो जाता है, तो आपके click की वजह से एक JavaScript function चला, उसने server को request भेजी, जवाब का इंतज़ार किया और पेज update किया।
Web applications टेस्ट करने के लिए JavaScript लिखना आना ज़रूरी नहीं है। आपको उसकी कुछ lines पढ़नी हैं, click और नतीजे के बीच क्या होता है यह समझना है, और script fail होने पर browser जो errors दिखाता है उन्हें पढ़ना है।
यह क्यों ज़रूरी है
आधुनिक web application में users जो कुछ करते हैं उसका ज़्यादातर हिस्सा JavaScript से होकर जाता है, और जब वह fail होती है तो पेज अक्सर ठीक ही दिखता है: button कुछ नहीं करता, spinner घूमता रहता है, price की जगह NaN दिखता है। अक्सर इकलौता सबूत browser console में एक लाल message होता है, जिसे users कभी नहीं देखते। जो tester console नहीं खोलता, वह ये failures miss कर देता है या "button काम नहीं करता" जैसी reports लिखता है जिन पर developer कुछ नहीं कर सकता।
JavaScript timing को भी behaviour का हिस्सा बना देती है: कई defects सिर्फ़ slow network पर, error response के बाद या दूसरे click के बाद दिखते हैं।
Variables, values और functions
Variable किसी value को रखने की नामवाली जगह है: const total = 150; दोबारा assign नहीं हो सकता, let qty = 1; हो सकता है। Values के types होते हैं: strings ('150'), numbers (150), booleans (true), objects ({ price: 25 }), arrays ([3, 5]), और undefined (कोई value set नहीं) या null (जान-बूझकर खाली)। Function नामवाला steps का block है जो तब चलता है जब कोई उसे call करे; उसे पढ़कर अक्सर पता चलता है कि developer कौन-से cases भूल गया, जैसे नीचे के उदाहरण में बिना product वाला cart item।
'5' + 1से'51'मिलता है: जब कोई एक side string हो, तो+गिनती का जोड़ करने की बजाय दोनों को text की तरह साथ चिपका देता है, और text field से पढ़ी value convert होने तक string रहती है। Cart 6 की जगह 51 items दिखा सकता है।'abc' * 2सेNaN(not a number) मिलता है, औरNaNवाली हर calculation का नतीजाNaNहोता है, जो screen पर price की जगह दिख सकता है।- Missing value text के रूप में इस्तेमाल हो तो "undefined" शब्द या खाली label दिखता है।
// cart.js: the kind of function you will read in a page
function lineTotal(item) {
const price = item.product.price; // a number, e.g. 25
const qty = Number(item.qty); // the field gives a string, e.g. '2'
return price * qty;
}
lineTotal({ product: { price: 25 }, qty: '2' }); // 50
lineTotal({ product: undefined, qty: '2' }); // throws a TypeErrorEvents और asynchronous code
पेज का ज़्यादातर code events का इंतज़ार करता है। Script किसी element से handler जोड़ता है, जैसे button.addEventListener('click', applyCoupon), और हर बार event होने पर browser उसे call करता है। आम events हैं click, input, change, submit और keydown। Handler सिर्फ़ अपने events पर चलता है: key presses सुनने वाली जाँच तब कभी नहीं चलती जब value mouse से paste हो या autofill उसे भर दे।
Server से बात करने में समय लगता है, इसलिए वह code asynchronous होता है। fetch() HTTP request भेजता है और तुरंत एक promise लौटाता है, यानी ऐसा object जो उस result की जगह खड़ा है जो अभी आया नहीं। Promise तब तक pending रहता है जब तक किसी value के साथ fulfilled या error के साथ rejected न हो; इस बीच await वाला code अपने async function के अंदर रुका रहता है और बाक़ी पेज इस्तेमाल लायक रहता है।
जवाब आने पर promise एक response object के साथ fulfil होता है, जिसे आम तौर पर res नाम दिया जाता है: res.ok सिर्फ़ 200 से 299 तक के statuses के लिए true होता है, और await res.json() body को JSON के रूप में पढ़ता है, यानी वह text format जिसमें ज़्यादातर APIs data भेजती हैं और जो काफ़ी हद तक JavaScript object जैसा लिखा जाता है। fetch() का promise सिर्फ़ तब reject होता है जब request ही fail हो, जैसे network error पर। 404 या 500 response भी उसे fulfil कर देता है, इसलिए code को res.ok जाँचना होता है।
fetch() का promise fulfil करता है, बिना जाँची body TypeError throw करती है और spinner घूमता रहता है।Valid coupon: 200 OK
- यूज़र
- पेज script ब्राउज़र में JavaScript
- सर्वर
- 1 यूज़र से पेज script तक: "Apply coupon" पर click करता है
clickevent handler को call करता है - 2 पेज script आंतरिक रूप से: Spinner दिखाता है
- 3 पेज script से सर्वर तक: Request भेजता है
fetch()तुरंत pending promise लौटाता है; पेज इस्तेमाल लायक रहता हैPOST /api/coupons/apply - 4 सर्वर से पेज script तक:
200 OKजवाब Discount वाली JSON body - 5 पेज script आंतरिक रूप से: Promise fulfilled:
data.discount.percentपढ़ता है Coderes.okनहीं जाँचता, पर इस body में discount है - 6 पेज script से यूज़र तक: नया total, spinner छिप जाता है जवाब
परिणाम: Code काम करता है, इसलिए सिर्फ़ valid coupons वाला test pass होता है और defect छिपा रहता है। पास
Expired coupon: 422
- यूज़र
- पेज script ब्राउज़र में JavaScript
- सर्वर
- 1 यूज़र से पेज script तक: "Apply coupon" पर click करता है Handler spinner दिखाता है
- 2 पेज script से सर्वर तक: Request भेजता है
POST /api/coupons/apply - 3 सर्वर से पेज script तक: 422: coupon मना जवाब
{"error":"COUPON_EXPIRED"} - 4 पेज script आंतरिक रूप से: Promise फिर भी fulfilled: 422 भी response है
res.okजाँचे बिना codedata.discount.percentपढ़ता है - 5 पेज script आंतरिक रूप से: TypeError throw होता है, कोई catch नहीं करता Function वहीं रुक जाता है; spinner छिपाने वाली line कभी नहीं चलती फ़ेल
- 6 पेज script से यूज़र तक: Spinner घूमता रहता है, कोई message नहीं जवाब इकलौता निशान console में "Uncaught (in promise)" है
परिणाम: यूज़र अटक जाता है; console error और 422 response ही bug report का सबूत हैं। फ़ेल
fetch() का promise सिर्फ़ तब reject होता है जब request ही fail हो, जैसे network error पर; 422 या 500 जैसा error status भी उसे fulfil कर देता है, इसलिए code को res.ok जाँचना होता है।
- Request pending रहते user दोबारा click कर सकता है, field बदल सकता है, पेज छोड़ सकता है। Duplicate requests और waiting state जाँचें।
- जवाब क्रम से बाहर आ सकते हैं: search box में "ri" का धीमा जवाब "riyadh" के नए जवाब को overwrite कर सकता है।
- कम से कम success, error status और बिलकुल कोई जवाब नहीं (offline या timeout) टेस्ट करें; slow जवाब waiting state दिखाता है।
आज़माएँ: API स्टेटस कोड सिम्युलेटर आज़माएँ: Mock एरर रिस्पॉन्स जनरेटर
JavaScript पेज को कैसे तोड़ती है
जब code exception throw करता है और कोई उसे catch नहीं करता, तो browser उस समय चल रहे code को छोड़ देता है, यानी वह function और उसे call करने वाला हर function, और console में error दर्ज करता है। दूसरे handlers और scripts चलते रहते हैं, इसलिए बाक़ी पेज आम तौर पर काम करता रहता है; सिर्फ़ वह feature चुप हो जाता है जो error से टकराया। ISTQB की भाषा में आप failure देखते हैं, जिसका कारण एक defect है जिसे किसी इंसान ने error (गलती) से डाला; JavaScript बस अपने exceptions को errors कहती है। आम failures:
- Button कुछ नहीं करता: उसके handler ने कुछ बदलने से पहले exception throw कर दिया।
- Spinner कभी नहीं रुकता या button disabled रहता है: उन्हें reset करने वाली line fail हुई line के बाद आती है।
- अजीब values, अक्सर बिना किसी error के, क्योंकि code गलत data के साथ अंत तक चला:
NaN,undefined,[object Object], 6 की जगह 51। - पूरा widget गायब: उसकी script file load नहीं हुई या उसमें syntax error है, इसलिए उसका कोई code नहीं चला।
- सिर्फ़ कुछ data पर fail: खाली list, missing optional field, deleted product।
Console error पढ़ना
Developer tools खोलें (ज़्यादातर desktop browsers में F12) और Console panel चुनें; बाक़ी panels DevTools वाले lesson में आएँगे। Console clear करें, action दोहराएँ और सिर्फ़ नए लाल errors पढ़ें। नीचे वह है जो पहले section का lineTotal, Chrome की wording में, तब दर्ज करता है जब cart item का product न हो।
- Type:
TypeError(गलत तरह की value पर operation, अक्सरundefined),ReferenceError(अनजाना नाम),SyntaxError(code या JSON जो parse न हो),RangeError(range से बाहर value)। - Message: यहाँ
undefinedसेpriceपढ़ना, यानीitem.productmissing था। पूछें कि किस data से ऐसा हुआ, जैसे catalogue से हटाया गया product। Wording browsers में अलग होती है; type नहीं। - Location: file, line और column,
cart.js:58:30। - Stack trace: सबसे ऊपर वह जगह जहाँ error throw हुआ, नीचे हर caller। कहानी के लिए नीचे से पढ़ें (button click ने एक बेनाम handler चलाया, जिसने
renderCartऔर फिरlineTotalको call किया)।Uncaughtका मतलब है किसी ने catch नहीं किया;(in promise)का मतलब है rejected promise। - Live sites आम तौर पर अपना code minify करती हैं, अक्सर एक लंबी line में (
app.3f9c1.js:1:20431); source maps developers को original file तक ले जाते हैं, और formatter उसे आपके पढ़ने लायक बनाता है।
Uncaught TypeError: Cannot read properties of undefined (reading 'price')
at lineTotal (cart.js:58:30)
at renderCart (cart.js:31:17)
at HTMLButtonElement.<anonymous> (cart.js:12:5)Worked example: "Apply coupon" button जो कभी ख़त्म नहीं होता
Checkout की exploratory testing में expired coupon WELCOME10 spinner को हमेशा घूमता छोड़ देता है; valid coupon काम करता है। Console clear करके tester steps दोहराता है और नीचे का सबूत इकट्ठा करता है।
- Server ने coupon को सही तरह
422(Unprocessable Content: request सही बनी थी, पर server ने उसका content process करने से मना किया) और error code के साथ मना किया। - फिर भी
fetch()का promise fulfil हुआ, और coderes.okनहीं जाँचता। Error body मेंdiscountनहीं है, इसलिए line 42TypeErrorthrow करती है और spinner छिपाने वाली line 43 कभी नहीं चलती। - Report: "Expired coupon spinner को चलता छोड़ देता है और कोई message नहीं दिखाता", steps, expected result (spinner हटे, coupon expire होने का message), actual result, console text और request व response के साथ। फिर बाक़ी नतीजे टेस्ट करें: unknown code, server error, slow जवाब, network नहीं, double click।
Console
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'percent')
at applyCoupon (checkout.js:42:44)
Network
POST /api/coupons/apply -> 422 {"error":"COUPON_EXPIRED"}
checkout.js
38 async function applyCoupon() {
39 spinner.hidden = false;
40 const res = await fetch(url, options);
41 const data = await res.json();
42 total.textContent = format(data.discount.percent);
43 spinner.hidden = true;
44 }आम गलतियाँ
- Console बंद रखकर टेस्ट करना और error text के बिना "button काम नहीं करता" report करना।
- Error की सिर्फ़ पहली line या उसका screenshot चिपकाना: type, message और stack trace text के रूप में copy करें।
- सिर्फ़ तेज़, successful responses टेस्ट करना, जबकि error statuses, slow जवाब, offline mode और double clicks पर ही asynchronous code टूटता है।
- Console के हर message को defect के रूप में file करना: कुछ browser extensions या third-party scripts से आते हैं, इसलिए पहले file देखें।
- User को दिखने वाला failure लिखने की बजाय console error को bug का title बना देना।
QA का नज़रिया
Web feature टेस्ट करते समय console खुला रखें, हर scenario से पहले clear करें, और हर नए लाल error की जाँच करें, चाहे screen ठीक दिखे। Action, पूरा text और ठीक पहले की request दर्ज करें; file और line से developer अक्सर defect जल्दी ढूँढ लेता है।
Reviews में server को call करने वाले हर action के लिए पूछें कि कौन-से responses संभव हैं और हर एक पर पेज को क्या करना चाहिए: success, validation error, server error, timeout, network नहीं, दूसरा click। जवाब आपकी test conditions बनते हैं, और यही timing के सवाल बाद में UI automation में waits के रूप में लौटते हैं।
अभ्यास
"Load more" button के पीछे का error पढ़ें
Order history पेज पर page 3 load करते समय "Load more" सिर्फ़ spinner दिखाता है; pages 1 और 2 काम करते हैं। नीचे के सबूत का विश्लेषण वैसे करें जैसे bug report लिखने से पहले करते हैं।
Console (Chrome)
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
Network
GET /api/orders?page=3 -> 502 Bad Gateway Content-Type: text/html
orders.js
12 async function loadMore(page) {
13 spinner.hidden = false;
14 const res = await fetch('/api/orders?page=' + page);
15 const orders = await res.json();
16 renderOrders(orders);
17 spinner.hidden = true;
18 }- Error type और वह line बताएँ जिसने उसे throw किया होगा।
- समझाएँ कि message में
<क्यों है औरfetch()का promise reject क्यों नहीं हुआ। - बताएँ कि user क्या देखता है और कौन-सी lines कभी नहीं चलतीं।
- तय करें कि क्या और किसे report करना है, और चार और tests लिखें।
मॉडल उत्तर दिखाएँ
SyntaxError: कुछ parse नहीं हो सका। Parse करने वाली इकलौती line 15 है, res.json(); Uncaught (in promise) पुष्टि करता है कि यह ऐसा rejected promise है जिसे किसी ने handle नहीं किया।
502 Bad Gateway किसी gateway या proxy से आता है, यानी API के आगे खड़ा server, जब उसे पीछे वाले server से invalid जवाब मिलता है। यहाँ body उसी gateway का HTML error page है (Content-Type: text/html) जो <!DOCTYPE से शुरू होता है, इसलिए JSON parsing < पर fail होती है। 502 भी एक response है, इसलिए fetch() का promise fulfil हुआ, और code res.ok नहीं जाँचता।
कभी न रुकने वाला spinner और कोई message नहीं। Lines 16 और 17 कभी नहीं चलतीं: orders नहीं जुड़ते और spinner कभी नहीं छिपता।
दो reports: back-end या operations team को, GET /api/orders?page=3 502 लौटाता है, request के समय के साथ; front-end developer को, failed load कोई message नहीं दिखाता और spinner छोड़ देता है, जबकि साफ़ message और इस्तेमाल लायक button expected है। और tests, उदाहरण के लिए: 500 और 504 responses, slow response, offline mode, खाली आख़िरी page, "Load more" पर double click।
अक्सर पूछे जाने वाले सवाल
क्या web applications टेस्ट करने के लिए मुझे JavaScript programming सीखनी होगी?
शुरुआत के लिए नहीं। Manual web testing के लिए variables, functions, events और promises पढ़ना और console errors समझना काफ़ी है। Cypress से browser tests automate करने के लिए आप JavaScript या TypeScript लिखेंगे, और Playwright के अपने test runner, Playwright Test, के लिए भी (Playwright के Python, Java और .NET versions भी हैं); यह lesson उन lessons की नींव है।
क्या JavaScript और Java एक ही हैं?
नहीं। ये अलग design वाली दो अलग languages हैं; नाम की समानता ऐतिहासिक है। JavaScript ECMA-262 standard में ECMAScript के नाम से standardised है, और TypeScript type annotations वाली JavaScript है जिसे browser में चलने से पहले JavaScript में compile किया जाता है।
क्या console का हर लाल message bug है?
ज़रूरी नहीं। लाल रंग errors के लिए है, जिनमें failed network requests भी शामिल हैं, और कुछ browser extensions या analytics जैसी third-party scripts से आते हैं। वह bug तब है जब वह product के अपने code या requests से आए और behaviour पर असर डाले, या जब team का नियम clean console का हो। पक्का न हो तो file और action नोट करें और developer से पूछें।
संदर्भ
- ECMAScript® Language Specification (ECMA-262)JavaScript भाषा का मानक, जिसमें RegExp का व्याकरण और अर्थ, JSON.parse/JSON.stringify और Date ऑब्जेक्ट शामिल हैं।
- Fetch StandardCORS को परिभाषित करता है: प्रीफ़्लाइट रिक्वेस्ट, Access-Control-* हेडर और कौन-से रिस्पॉन्स ब्राउज़र पेज को दिखा सकता है।
- ISTQB Glossaryटेस्टिंग शब्दों की मानक परिभाषाएँ — टेस्ट केस, रिग्रेशन टेस्टिंग, सेवेरिटी, प्रायोरिटी, बाउंड्री वैल्यू एनालिसिस आदि।
- JavaScript — MDNMDN की JavaScript गाइड और reference: भाषा का सिंटैक्स, types, objects और built-ins, जैसे ब्राउज़र उन्हें लागू करते हैं।
Mutqan tools से अभ्यास करें
JavaScript और TypeScript कोड को एकसमान इंडेंटेशन और स्पेसिंग के साथ सुंदर बनाएँ।
ऐसा सार्वजनिक endpoint पाएँ जो कोई भी HTTP स्टेटस कोड लौटाए, वैकल्पिक देरी और कस्टम JSON बॉडी के साथ, ताकि क्लाइंट की error हैंडलिंग टेस्ट हो सके।
लोकप्रिय फ़ॉर्मेट में संरचित एरर रिस्पॉन्स बनाएँ (validation, auth, not found, rate limit, सर्वर एरर)।
success, list, detail, error और empty केस के लिए पूरे mock API रिस्पॉन्स (स्टेटस, हेडर, JSON बॉडी) बनाएँ।
JSON सिंटैक्स वैलिडेट करें और गलतियों की सटीक जगह के साथ सुधार के उपयोगी सुझाव पाएँ।
किसी भी HTTP स्टेटस कोड का अर्थ, RFC संदर्भ और उसे कब इस्तेमाल करना है — सब एक जगह देखें।
और गहराई से
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।