ऑटोमेटेड टेस्ट, बुनियादी तौर पर सिर्फ़ ऐसा कोड होते हैं जिससे कुछ गलत होने पर गड़बड़ी हो सकती है या गड़बड़ी हो सकती है. ज़्यादातर लाइब्रेरी या टेस्टिंग फ़्रेमवर्क में कई तरह के प्रिमिटिव होते हैं, जो टेस्ट को लिखना आसान बना देते हैं.
जैसा कि पिछले सेक्शन में बताया गया है, इन प्रिमिटिव में हमेशा इंडिपेंडेंट टेस्ट (जिसे टेस्ट केस कहा जाता है) तय करने और दावा करने का तरीका शामिल होता है. दावे, किसी नतीजे की जांच करने और अगर कुछ गलत होने पर गड़बड़ी को फेंकने का एक तरीका है, तो इसे सभी टेस्टिंग प्रिमिटिव का बुनियादी बुनियादी माना जा सकता है.
इस पेज में इन प्रिमिटिव के बारे में सामान्य जानकारी दी गई है. आपके चुने गए फ़्रेमवर्क में ऐसा कुछ होने की संभावना होती है. हालांकि, यह सटीक रेफ़रंस नहीं है.
उदाहरण के लिए:
import { fibonacci, catalan } from '../src/math.js';
import { assert, test, suite } from 'a-made-up-testing-library';
suite('math tests', () => {
test('fibonacci function', () => {
// check expected fibonacci numbers against our known actual values
// with an explanation if the values don't match
assert.equal(fibonacci(0), 0, 'Invalid 0th fibonacci result');
assert.equal(fibonacci(13), 233, 'Invalid 13th fibonacci result');
});
test('relationship between sequences', () => {
// catalan numbers are greater than fibonacci numbers (but not equal)
assert.isAbove(catalan(4), fibonacci(4));
});
test('bugfix: check bug #4141', () => {
assert.isFinite(fibonacci(0)); // fibonacci(0) was returning NaN
})
});
यह उदाहरण टेस्ट का एक ग्रुप बनाता है (कभी-कभी इसे सुइट भी कहा जाता है) जिसे "गणित के टेस्ट" कहा जाता है. इसमें तीन इंडिपेंडेंट टेस्ट केस तय किए गए हैं, जिनमें से हर एक में कुछ दावे किए जाते हैं. आम तौर पर, इन टेस्ट केस को अलग-अलग देखा जा सकता है या चलाया जा सकता है. उदाहरण के लिए, आपके टेस्ट रनर में फ़िल्टर फ़्लैग का इस्तेमाल करके.
प्रिमिटिव के तौर पर असर डालने वाले हेल्पर
Vitest समेत ज़्यादातर टेस्टिंग फ़्रेमवर्क में assert
ऑब्जेक्ट पर दावा करने में मदद करने वाले हेल्पर का कलेक्शन शामिल होता है. इससे आपको कुछ expectation के लिए, रिटर्न वैल्यू या अन्य स्थितियों की तुरंत जांच करने की सुविधा मिलती है. यह उम्मीद अक्सर "अच्छे" वैल्यू होती हैं. ऊपर दिए गए उदाहरण में, हम जानते हैं कि 13वीं फिबोनाशी संख्या, 233 होनी चाहिए, इसलिए हम सीधे assert.equal
का इस्तेमाल करके इसकी पुष्टि कर सकते हैं.
आपको यह भी उम्मीद हो सकती है कि कोई वैल्यू किसी खास रूप में हो, किसी दूसरी वैल्यू से ज़्यादा हो या उसकी कोई दूसरी प्रॉपर्टी हो. इस कोर्स में, दावा करने में मदद करने वाले सभी तरह के संभावितों के बारे में नहीं बताया गया है. हालांकि, टेस्टिंग फ़्रेमवर्क में कम से कम ये बुनियादी जांच मौजूद होती हैं:
'सही' जांच, जिसे अक्सर 'ठीक है' जांच के तौर पर बताया जाता है. इससे यह पता चलता है कि कोई शर्त सही है या नहीं. यह जांच करता है कि
if
को कैसे लिखा जा सकता है, जो यह जांचता है कि कोई चीज़ सही है या सही. इसेassert(...)
याassert.ok(...)
के तौर पर दिया जाता है और इसमें एक वैल्यू और एक वैकल्पिक टिप्पणी होती है.गणित की जांच की तरह, बराबरी की जांच, जिसमें आपको उम्मीद है कि किसी ऑब्जेक्ट की रिटर्न वैल्यू या स्थिति, किसी अच्छी वैल्यू के बराबर होगी. ये पहले से मौजूद बराबरी (जैसे कि संख्याओं और स्ट्रिंग के लिए) या रेफ़रेंशियल समानता के लिए हैं. क्या ये दोनों एक ही ऑब्जेक्ट के लिए हैं. हुड के तहत, ये
==
या===
की तुलना के साथ सिर्फ़ एक 'सही' जांच हैं.- JavaScript, ढीली (
==
) और सख्त (===
) समानता के बीच अंतर करता है. ज़्यादातर टेस्ट लाइब्रेरी आपकोassert.equal
औरassert.strictEqual
तरीके उपलब्ध कराती हैं.
- JavaScript, ढीली (
डीप बराबरी की जांच, जिसमें बराबरी की जांच का दायरा बढ़ाया जाता है. इसमें ऑब्जेक्ट, अरे, और दूसरे ज़्यादा जटिल डेटा टाइप की जांच करना शामिल होता है. साथ ही, ऑब्जेक्ट को ट्रैवर्स करने के लिए अंदरूनी लॉजिक की भी जांच की जाती है. ये इसलिए ज़रूरी हैं, क्योंकि JavaScript में दो ऑब्जेक्ट या अरे के कॉन्टेंट की तुलना करने का तरीका पहले से मौजूद नहीं है. उदाहरण के लिए,
[1,2,3] == [1,2,3]
हमेशा गलत होता है. टेस्ट फ़्रेमवर्क में अक्सरdeepEqual
याdeepStrictEqual
हेल्पर शामिल होते हैं.
दो वैल्यू की तुलना करने वाले दावा हेल्पर (सिर्फ़ 'सही' जांच के बजाय) आम तौर पर दो या तीन आर्ग्युमेंट इस्तेमाल करते हैं:
- जांच में मौजूद कोड से जनरेट की गई असल वैल्यू या पुष्टि किए जाने वाले स्टेटस के बारे में बताने वाली वैल्यू.
- उम्मीद के मुताबिक वैल्यू, आम तौर पर हार्ड कोड किया गया (उदाहरण के लिए, लिटरल वैल्यू या स्ट्रिंग).
- एक वैकल्पिक टिप्पणी जो बता सकती है कि क्या उम्मीद थी या क्या नहीं हो सका. अगर यह लाइन काम नहीं करती, तो उसे शामिल कर लिया जाएगा.
कई तरह की जांच करने के लिए, दावों को एक साथ जोड़ना भी आम बात है. ऐसा बहुत कम होता है कि कोई व्यक्ति, आपके सिस्टम की स्थिति की सही तरीके से खुद-ब-खुद पुष्टि कर सके. उदाहरण के लिए:
test('JWT parse', () => {
const json = decodeJwt('eyJieSI6InNhbXRob3Ii…');
assert.ok(json.payload.admin, 'user should be admin');
assert.deepEqual(json.payload.groups, ['role:Admin', 'role:Submitter']);
assert.equal(json.header.alg, 'RS265')
assert.isAbove(json.payload.exp, +new Date(), 'expiry must be in future')
});
Vitest ने अपने दावा करने में मदद करने वाले हेल्पर उपलब्ध कराने के लिए, अंदरूनी तौर पर Chai assertion Library का इस्तेमाल किया है. साथ ही, इसके रेफ़रंस से यह पता लगाने में मदद मिल सकती है कि आपके कोड के लिए कौनसे दावे और मददगार टूल सही हो सकते हैं.
धाराप्रवाह और BDD दावे
कुछ डेवलपर, दावे करने की ऐसी स्टाइल पसंद करते हैं जिसे व्यवहार-आधारित डेवलपमेंट (बीडीडी) या फ़्लुएंट-स्टाइल दावा कहा जा सकता है. इन्हें "उम्मीद" हेल्पर भी कहा जाता है, क्योंकि उम्मीदों की जांच करने का शुरुआती तरीका expect()
है.
उम्मीद रखने वाले हेल्पर, दावों को assert.ok
या assert.strictDeepEquals
जैसे आसान तरीकों वाले कॉल की तरह ही काम करते हैं, लेकिन कुछ डेवलपर को इन्हें पढ़ना आसान लगता है.
BDD दावा इस तरह से हो सकता है:
// A failure here would generate "Expect result to be an array that does include 42"
const result = await possibleMeaningsOfLife();
expect(result).to.be.an('array').that.does.include(42);
// or a simpler form
expect(result).toBe('array').toContainEqual(42);
// the same in assert might be
assert.typeOf(result, 'array', 'Expected the result to be an array');
assert.include(result, 42, 'Expected the result to include 42');
दावे के ये तरीके, मेथड चेन नाम की तकनीक की वजह से काम करते हैं. इसमें expect
से लौटाए गए ऑब्जेक्ट को दूसरे तरीकों के कॉल के साथ लगातार चेन किया जा सकता है. कॉल के कुछ हिस्सों में कोई फ़ंक्शन नहीं होता है, जैसे कि to.be
और पिछले उदाहरण में that.does
. इन्हें सिर्फ़ पढ़ने में आसान बनाने के लिए शामिल किया जाता है. साथ ही, जांच पूरी न होने पर, ये हिस्से अपने-आप जनरेट होने वाली टिप्पणी जनरेट कर सकते हैं. (ध्यान दें, expect
पर आम तौर पर कोई भी टिप्पणी नहीं की जा सकती, क्योंकि चेन में गड़बड़ी के बारे में साफ़ तौर पर बताया जाना चाहिए.)
कई टेस्ट फ़्रेमवर्क, Fluent/BDD और सामान्य दावों, दोनों के साथ काम करते हैं. उदाहरण के लिए, Vitest का दोनों ही तरीकों को एक्सपोर्ट करता है. साथ ही, BDD के लिए उसका थोड़ा ज़्यादा सटीक नज़रिया है. दूसरी ओर, जेस्ट में डिफ़ॉल्ट रूप से सिर्फ़ उम्मीद तरीका शामिल होता है.
सभी फ़ाइलों के लिए ग्रुप टेस्ट
टेस्ट लिखते समय, हम पहले से ही इंप्लिसिट ग्रुपिंग देते हैं. सभी टेस्ट एक ही फ़ाइल में होने के बजाय, कई फ़ाइलों में टेस्ट लिखना आम बात है. टेस्ट रनर आम तौर पर, यह जानते हैं कि फ़ाइल, पहले से तय किए गए फ़िल्टर या रेगुलर एक्सप्रेशन की वजह से टेस्ट के लिए है. उदाहरण के लिए, vitest. उदाहरण के लिए, इसमें आपके प्रोजेक्ट की वे सभी फ़ाइलें शामिल होती हैं जो ".test.jsx" या ".spec.ts" (".test" और ".spec") जैसे एक्सटेंशन पर खत्म होती हैं. साथ ही, कई मान्य एक्सटेंशन होती हैं.
कॉम्पोनेंट टेस्ट की जांच, आम तौर पर टेस्ट के तहत कॉम्पोनेंट की एक पीयर फ़ाइल में की जाती है, जैसा कि इस डायरेक्ट्री के स्ट्रक्चर में किया गया है:
इसी तरह, यूनिट टेस्ट को टेस्ट के तहत आने वाले कोड के बगल में रखा जाता है. एंड-टू-एंड टेस्ट हर तरह की अपनी फ़ाइल में हो सकते हैं. साथ ही, इंटिग्रेशन की जांच को अपने यूनीक फ़ोल्डर में भी रखा जा सकता है. ये स्ट्रक्चर तब मददगार होते हैं, जब मुश्किल टेस्ट केस बढ़ जाते हैं और उन्हें खुद की बिना टेस्ट वाली सपोर्ट फ़ाइलों की ज़रूरत पड़ती है. जैसे, ऐसी सपोर्ट लाइब्रेरी जो सिर्फ़ जांच के लिए ज़रूरी होती हैं.
फ़ाइलों में ग्रुप टेस्ट
जैसा कि पहले दिए गए उदाहरणों में बताया गया है, आम तौर पर suite()
को किए गए कॉल में टेस्ट को शामिल किया जाता है. ये टेस्ट, test()
के साथ सेट अप किए गए टेस्ट का ग्रुप बनाते हैं. आम तौर पर, सुइट
टेस्ट नहीं करते हैं. हालांकि, वे पास किए गए तरीके को कॉल करके मिलते-जुलते टेस्ट या लक्ष्यों
का ग्रुप बनाकर स्ट्रक्चर उपलब्ध कराने में मदद करते हैं. test()
के लिए, पास हो चुका तरीका टेस्ट की कार्रवाइयों के बारे में बताता है.
दावों की तरह, ग्रूपिंग टेस्ट के लिए Fluent/BDD में काफ़ी मानक समानता है. नीचे दिए गए कोड में, कुछ सामान्य उदाहरणों की तुलना की गई है:
// traditional/TDD
suite('math tests', () => {
test('handle zero values', () => {
assert.equal(fibonacci(0), 0);
});
});
// Fluent/BDD
describe('math tests', () => {
it('should handle zero values', () => {
expect(fibonacci(0)).toBe(0);
});
})
ज़्यादातर फ़्रेमवर्क में suite
और describe
, test
और it
की तरह ही व्यवहार करते हैं, क्योंकि दावे लिखने के लिए expect
और assert
का इस्तेमाल करने के बीच ज़्यादा अंतर है.
दूसरे टूल में, सुइट और टेस्ट की व्यवस्था करने का तरीका अलग-अलग होता है. उदाहरण
के लिए, Node.js में पहले से मौजूद टेस्ट रनर टूल, test()
पर नेस्टिंग कॉल के साथ काम करता है, ताकि अनुमान से टेस्ट हैरारकी बनाई जा सके. हालांकि, Vitest सिर्फ़ suite()
का इस्तेमाल करके इस तरह के नेस्ट करने की अनुमति देता है और किसी दूसरे test()
में तय किए गए test()
को नहीं चलाएगा.
दावों की तरह ही, याद रखें कि आपके टेक्नोलॉजी स्टैक में मौजूद ग्रुप के तरीकों का सटीक कॉम्बिनेशन वह ज़रूरी नहीं है. इस कोर्स में इनके बारे में एब्सट्रैक्ट जानकारी दी गई है, लेकिन आपको यह पता लगाना होगा कि ये टूल आपकी पसंद के टूल पर कैसे लागू होते हैं.
लाइफ़साइकल के तरीके
अपने टेस्ट को ग्रुप करने का एक वजह, यहां तक कि किसी फ़ाइल में टॉप लेवल पर भी, सेटअप और टियरडाउन के तरीके उपलब्ध कराना है, जो हर टेस्ट के लिए या टेस्ट के समूह के लिए एक बार चलते हैं. ज़्यादातर फ़्रेमवर्क चार तरीके से काम करते हैं:
हर `test()` या `it()` के लिए | सुइट के लिए एक बार | |
---|---|---|
टेस्ट करने से पहले | `पहले हर()` | `beforeAll()` |
जांच के बाद | `बाद में हर()` | `afterAll()` |
उदाहरण के लिए, हो सकता है कि आप हर जांच से पहले, वर्चुअल उपयोगकर्ता के डेटाबेस को अपने-आप भर देना चाहें और बाद में मिटाना चाहें:
suite('user test', () => {
beforeEach(() => {
insertFakeUser('bob@example.com', 'hunter2');
});
afterEach(() => {
clearAllUsers();
});
test('bob can login', async () => { … });
test('alice can message bob', async () => { … });
});
इससे, जांच को आसान बनाने में मदद मिल सकती है. हर टेस्ट में कोड को डुप्लीकेट करने के बजाय, सामान्य सेटअप और टियरडाउन कोड को शेयर किया जा सकता है. इसके अलावा, अगर सेटअप और टियरडाउन कोड से अपने-आप कोई गड़बड़ी होती है, तो इसका मतलब है कि सिस्टम से जुड़ी उन समस्याओं की जानकारी मिल सकती है जो टेस्ट में फ़ेल होने की वजह से पूरी नहीं हो पाती हैं.
सामान्य सलाह
इन प्रिमिटिव के बारे में सोचते समय याद रखने वाली कुछ सलाह यहां दी गई हैं.
प्रिमिटिव एक गाइड होते हैं
ध्यान रखें कि यहां दिए गए टूल और प्रिमिटिव और अगले कुछ पेजों में दिए गए टूल, Vitest, Jest या Mocha या Web Test Runner या किसी अन्य खास फ़्रेमवर्क से पूरी तरह मेल नहीं खाएंगे. हालांकि हमने Vitest का इस्तेमाल सामान्य गाइड के तौर पर किया है, लेकिन उन्हें अपनी पसंद के फ़्रेमवर्क के साथ मैप करना न भूलें.
ज़रूरत के हिसाब से दावों को मिलाएं और मैच करें
टेस्ट बुनियादी तौर पर ऐसे कोड होते हैं जिनसे गड़बड़ियां हो सकती हैं. हर रनर को अलग-अलग टेस्ट केस के बारे में बताने के लिए, एक शुरुआती test()
मिलेगा.
अगर वह रनर, assert()
, expect()
और दावे हेल्पर भी मुहैया कराता है, तो याद रखें कि यह हिस्सा सुविधा के बारे में ज़्यादा जानकारी देने वाला है. ज़रूरत पड़ने पर, इसे स्किप किया जा सकता है. आपके पास ऐसा कोई भी कोड चलाने का विकल्प होता है जिसमें गड़बड़ी हो. इसमें अन्य गारंटी लाइब्रेरी या पुराने ज़माने का if
स्टेटमेंट शामिल है.
IDE सेटअप से, कई चीज़ों की बचत हो सकती है
यह पक्का करें कि आपके IDE, जैसे कि VSCode के पास अपने-आप पूरा होने का ऐक्सेस है और आपके चुने हुए टेस्ट टूल से जुड़े दस्तावेज़ हैं. इससे आपकी परफ़ॉर्मेंस बेहतर हो सकती है. उदाहरण
के लिए, चाई दावे लाइब्रेरी में assert
पर 100 से ज़्यादा तरीके हैं. साथ ही, सही दावे को इनलाइन दिखाना आसान हो सकता है.
यह खास तौर पर कुछ टेस्ट फ़्रेमवर्क के लिए ज़रूरी हो सकता है, जो ग्लोबल नेमस्पेस को उनके जांच के तरीकों से भर देते हैं. यह एक मामूली अंतर है, लेकिन अगर लाइब्रेरी को ग्लोबल नेमस्पेस में अपने-आप जोड़ दिया जाता है, तो उन्हें इंपोर्ट किए बिना टेस्ट करने के लिए आम तौर पर उनका इस्तेमाल किया जा सकता है:
// some.test.js
test('using test as a global', () => { … });
हमारा सुझाव है कि हेल्पर को इंपोर्ट करें भले ही वे अपने-आप काम करते हों. ऐसा इसलिए, क्योंकि इससे आपके आईडीई को इन तरीकों को आसानी से ढूंढने में मदद मिलती है. (हो सकता है कि आपको React बनाते समय इस समस्या का सामना करना पड़ा हो, क्योंकि कुछ कोड बेस में एक मैजिक होता है
React
ग्लोबल, लेकिन कुछ कोड बेस में नहीं होता है. आपको इसे React का इस्तेमाल करके सभी फ़ाइलों में इंपोर्ट करना पड़ता है.)
// some.test.js
import { test } from 'vitest';
test('using test as an import', () => { … });