Node.js टेस्ट रनर के साथ प्रयोग

May 03 2023
Node.js 18 का विमोचन एक आश्चर्य के साथ आया: एक परीक्षण धावक, यद्यपि एक प्रायोगिक ध्वज के पीछे।
अनस्प्लैश पर जॉर्ज रोसल द्वारा फोटो

Node.js 18 का विमोचन एक आश्चर्य के साथ आया: एक परीक्षण धावक, यद्यपि एक प्रायोगिक ध्वज के पीछे।

मोचा और जेस्ट पिछले एक दशक से इस शून्य को भरने के साथ, क्या यह इस मूल परीक्षण धावक पर स्विच करने का समय है? केवल टेस्ट सूट चलाने के लिए कोई और देव निर्भरता नहीं है?

पेचीदा लगता है!

पहला प्रयास

testमैंने फ़ाइल में चरण को इसके साथ बदलकर प्रारंभ किया package.json:

{
  "scripts": {
    "test":  "node --test test/**/*.js"
  }
}

कंसोल में ढेर सारी त्रुटियां:

not ok * - <test path>
  ---
  duration_ms: 1028.112875
  failureType: 'subtestsFailed'
  exitCode: 1
  stdout: ''
  stderr: |-
    <test path>
    ^
    
    ReferenceError: describe is not defined
        at Object.<anonymous> (<test path>)
        at Module._compile (node:internal/modules/cjs/loader:1159:14)
        at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
        at Module.load (node:internal/modules/cjs/loader:1037:32)
        at Module._load (node:internal/modules/cjs/loader:878:12)
        at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
        at node:internal/main/run_main_module:23:47
    
    Node.js v18.12.1
    
  error: 'test failed'
  code: 'ERR_TEST_FAILURE'
  ...

const { describe, it, beforeEach, afterEach } = require('node:test');

// package.json

{
  "scripts": {
    "test":  "node --test -r test.setup.js test/**/*.js"
  }
}
// test.setup.js

global.describe = require('node:test').describe;
global.it = require('node:test').it;
global.beforeEach = require('node:test').beforeEach;
global.afterEach = require('node:test').afterEach;
global.before = require('node:test').before;
global.after = require('node:test').after;

Unable to resolve path to module 'node:test'. eslint(import/no-unresolved)

// .eslintrc.yml

settings:
  import/core-modules: [ node:test ]

अभी भी त्रुटियों का भार:

# Subtest: Errors thrown should be handled
not ok 3 - Errors thrown should be handled
---
duration_ms: 0.116958
failureType: 'hookFailed'
error: 'failed running beforeEach hook'
code: 'ERR_TEST_FAILURE'
stack: |-
  checkWrappedMethod (node_modules/sinon/lib/sinon/util/core/wrap-method.js:67:21)
  wrapMethod (node_modules/sinon/lib/sinon/util/core/wrap-method.js:132:13)
  stub (node_modules/sinon/lib/sinon/stub.js:130:44)
  node_modules/sinon/lib/sinon/util/core/walk-object.js:41:17
  node_modules/sinon/lib/sinon/util/core/walk.js:28:22
  Array.forEach (<anonymous>)
  walkInternal (node_modules/sinon/lib/sinon/util/core/walk.js:20:5)
  walk (node_modules/sinon/lib/sinon/util/core/walk.js:48:12)
  walkObject (node_modules/sinon/lib/sinon/util/core/walk-object.js:26:5)
  Function.stub (node_modules/sinon/lib/sinon/stub.js:103:16)
  extendObjectWithWrappedMethods (node_modules/sinon/lib/sinon/util/core/wrap-method.js:167:34)
  wrapMethod (node_modules/sinon/lib/sinon/util/core/wrap-method.js:155:5)
  stub (node_modules/sinon/lib/sinon/stub.js:130:44)
  node_modules/sinon/lib/sinon/util/core/walk-object.js:41:17
  node_modules/sinon/lib/sinon/util/core/walk.js:28:22
  Array.forEach (<anonymous>)
  walkInternal (node_modules/sinon/lib/sinon/util/core/walk.js:20:5)
  walk (node_modules/sinon/lib/sinon/util/core/walk.js:48:12)
  walkObject (node_modules/sinon/lib/sinon/util/core/walk-object.js:26:5)
  Function.stub (node_modules/sinon/lib/sinon/stub.js:103:16)
  ...

दूसरा प्रयास

इस बार मैं v18.16.0Node.js के LTS संस्करण का उपयोग कर रहा था। कोई और अधिक गुप्त त्रुटियाँ नहीं! वह एक राहत थी।

कवरेज रिपोर्ट चलाई। 45% कवरेज! हुह? इंतज़ार। हमारे 60% परीक्षण भी नहीं चलाए गए थे!

कुछ शोध करने से मुझे इस गिटहब मुद्दे पर ले जाया गया - टेस्ट रनर के लिए ग्लोब पार्सिंग वाला एक मुद्दा। एक बुनियादी सुविधा की तरह लग रहा था, लेकिन हाँ, गायब! test/**/*.jsइसलिए हम ग्लोब पैटर्न का उपयोग नहीं कर सकते ।

यदि नामित निर्देशिका का सामना करना पड़ता है, तो परीक्षण धावक इसे सभी , और फ़ाइलों testके लिए पुनरावर्ती रूप से खोजेगा ।.js.cjs.mjs

https://nodejs.org/docs/latest-v18.x/api/test.html#test-runner-execution-model

सौभाग्य से हमारी परीक्षण निर्देशिका का वास्तव में नाम था test। तो अब और ग्लोब नहीं।

// package.json

{
  "scripts": {
    "test":  "node --test -r test.setup.js"
  }
}

तीसरी कोशिश?

टेस्ट सूट आखिरकार हरा था। कवरेज भी हरा था।

अगला सभी कॉलों को बदलकर sinon.assertमूल निवासी से दूर माइग्रेट करना था :node:assert

sinon.assert.pass(condition);
sinon.assert.match(expected, received);

const assert = require('node:assert/strict');

assert.ok(condition);
assert.equal(expected, received);

टेस्ट सूट अभी भी हरा है। कवरेज भी हरा है। लेकिन प्रदर्शन नाले के नीचे था। हम्म, यह कुछ ऐसा है जिसे मैंने पहले नहीं देखा था।

परीक्षण सुइट को चलाने में 16 सेकंड से अधिक का समय लगा, जबकि मोचा एक सेकंड से भी कम समय में समाप्त हो गया! यहां तक ​​कि जेस्ट का भी मोचा जैसा ही समय था।

एक देशी टेस्ट रनर का उपयोग करने की मेरी धारणा यह थी कि यह मोचा और जेस्ट जैसे तीसरे पक्ष के टूल से बेहतर प्रदर्शन कर सकता है। लेकिन ऐसा प्रतीत नहीं होता है, जैसा कि इस GitHub मुद्दे से स्पष्ट है ।

इसलिए हमें तीसरा प्रयास करने के लिए Node.js की अगली छोटी रिलीज तक इंतजार करना होगा!

अंतिम विचार

Unsplash पर कैरोलिना द्वारा फोटो

तृतीय-पक्ष निर्भरता स्थापित किए बिना परीक्षण सूट चलाने में सक्षम होने के नाते निश्चित रूप से इसके गुण हैं। इसके अलावा, मोचा-जैसे सिंटैक्स के लिए समर्थन माइग्रेशन को आसान बनाता है।

और भी बहुत सी विशेषताएं हैं जिन्हें मैं आज़माना चाहता था: मॉक, स्नैपशॉट, कोड कवरेज, वॉचर्स, और बहुत कुछ।

लेकिन प्रदर्शन वास्तव में एक पुट-ऑफ था। ठीक होने का बेसब्री से इंतज़ार!