Практычныя нататкі: убудаваны тэст-раннер Node, Jest і Vitest — адзін набор, тры вынікі
Практычны разбор тэмы «убудаваны тэст-раннер Node супраць Jest і Vitest на адным наборы тэстаў»: кантракты, праверкі і гатовыя фрагменты кода для каманд, якія ўкараняюць гэты падыход.
Крыніцы: Node’s Native Test Runner vs Jest vs Vitest: One Suite, Three Runners, Real Timings
Існавайце гэта як перапрацоўку ідэй з артыкула “Node’s Native Test Runner vs Jest vs Vitest: One Suite, Three Runners, Real Timings” для аператараў: чыстыя этапы, арранжаваныя блакі коду і прыметкі па восстанавленню, якія застаюцца пасля перадачы задання. Этап “Апглэв” найкрашча працюе, калі яго спрыяваць як мерыемую плошчу. Запісаўце адну ідэальную транскрыпцыю, адзін кейс абярэння і прыметкі па вярненню да пачатковага стану прычым расшырэнню масштаба. Спрыяйце гэты этап як кантракт між вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце крытэрыя успеху і адмовіцеся ад тыхняга частковага завершэння без паведамлення.
Тры атрыбуты, чыста правду
Для трохціх учаснікаў, які чыста выкананяюць задачу, перш чым зменіць код, неабходна чыткая візначэння вхідных дадзеных, абавесця крока і крэтарыў завершэння. Аперацыйныя працавнікі должны магчымае перадзваніць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Запісваць час выканання і кост токенаў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівае паказанне костаў запобегае неспадзяваным рахункам, калі працэс пераходзіць з дэмавай версіі ў спяльныя сераўы. Стан неабходна размешчаць разам з компонентам, які керуе мутацыямі. Размешчэнне всего ў глобальным хранільніку ускладняе выяўленне багоў, зв’язаных з часам выканання.
1. node:test – нудны выбар, які проста работае
Для тэста з 1 вузлам неабяжна на стадыі прадэфінаваць вхідныя даны, адпаведальнага за крок і крытэрыя завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы схованы стан. Конфігурацыю трэба залічыць пазначальна ад коду прыкладнення. Файлы сераўіса, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць, не чытаяўшы весь ланцуг. Стан трэба размешчаць разам з компонентам, які керуе мутацыяй. Размешчэнне всего ў глобальным хранільніку ускладняе выяўленне багоў, зв’язаных з часам адпаведнай дзеяння.
// node-test/test/string-utils.test.js
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { slugify } from '../../src/string-utils.js';
describe('slugify', () => {
it('converts a basic sentence', () => {
assert.equal(slugify('Hello World'), 'hello-world');
});
it('strips diacritics', () => {
assert.equal(slugify('Café résumé'), 'cafe-resume');
});
it('throws TypeError on non-string input', () => {
assert.throws(() => slugify(123), TypeError);
});
});
# Run it, no install step
node --test node-test/test/*.test.js
# Watch mode
node --test --watch node-test/test/*.test.js
# Coverage (still experimental, but the numbers are real V8 counts)
node --test --experimental-test-coverage \
--test-coverage-include='src/**/*.js' \
node-test/test/*.test.js
2. Jest – стандартны выбар
Для стандартнага ўражэйства 2 Jest неабходная ўстановіць вхідныя даны, адпаведальнага за крок і крэтарыі выходу пры перадзеяванні коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Неабходна адначасна документацыя успішнага і варотнага падчасоў. Перапрыбуткі, людзкія перакрыцця і апрацоўка некорэктных паведамленняў ёсць часткай продукту, а не наступным этапам дапрацоўкі. Стан неабходна размешчаць разам з компонентам, які керуе мутацыяй. Перанесенне усяго у глобальны хранільнік ускладняе выяўленне багоў з часавымі параметрамі. Для стандартнага ўражэйства 2 Jest неабходная ўстановіць вхідныя даны, адпаведальнага за крок і крэтарыі выходу пры перадзеяванні коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Спрыяйце цэму ўражэйству як кантракту межаў вхідных дадзеных і перакананых выходных рэзультатаў. Даць назвы артыфактам, установіць перакрыцця успеху і адмовіцца ад беззвучнага частковага завершэння.
// jest/test/string-utils.test.js
import { slugify } from '../../src/string-utils.js';
describe('slugify', () => {
it('converts a basic sentence', () => {
expect(slugify('Hello World')).toBe('hello-world');
});
it('strips diacritics', () => {
expect(slugify('Café résumé')).toBe('cafe-resume');
});
it('throws TypeError on non-string input', () => {
expect(() => slugify(123)).toThrow(TypeError);
});
});
// jest/jest.config.js, minimal. Run it with NODE_OPTIONS=--experimental-vm-modules
export default {
rootDir: '.',
testMatch: ['<rootDir>/test/**/*.test.js'],
testEnvironment: 'node',
verbose: true,
};
# Run (the flag is required for native ESM)
NODE_OPTIONS=--experimental-vm-modules npx jest --config jest/jest.config.js
# Watch
NODE_OPTIONS=--experimental-vm-modules npx jest --config jest/jest.config.js --watch
3. Vitest – новы ўсталоўлены варыянт, з адной прычыною для паслядрозгледу
Калі працуеце з новым етапам Vitest, спачатку запісайце умовы контракту: неабходныя даны, сігнал успеху і тое, што выходзіць на падчасныя неудачы. Такі чарт дапамагае залічваць пазнейшыя змены ў кодзе адкрыта. Запісвайце час выканання і вартасць токена або запыту па боку рэзультатаў функцыяналу. Відразка вартасці з самага пачатку запобегае неспакойным рахункам, калі праця пераходзіць з дэмаверсіі ў спакульнаныя сераўысы. Расследвуйце наследкі як сінхронізацыю з зовнішнім светам, а не як замену вырахаваных значэнняў пад час адрасавання.
// vitest/test/string-utils.test.js
import { describe, it, expect } from 'vitest';
import { slugify } from '../../src/string-utils.js';
describe('slugify', () => {
it('converts a basic sentence', () => {
expect(slugify('Hello World')).toBe('hello-world');
});
it('strips diacritics', () => {
expect(slugify('Café résumé')).toBe('cafe-resume');
});
it('throws TypeError on non-string input', () => {
expect(() => slugify(123)).toThrow(TypeError);
});
});
// vitest/vitest.config.mjs
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
include: ['test/**/*.test.js'],
environment: 'node',
coverage: { provider: 'v8', include: ['../src/**/*.js'] },
},
});
# Run
cd vitest && npx vitest run
# Watch (this is the killer feature)
cd vitest && npx vitest
# Coverage
cd vitest && npx vitest run --coverage
Методалогія, каб вы маглі скарыстацца ёю
Калі працуеце з метадыямай, якія павінны быць выкарыстоўваны на разных этапах, спачатку запісайце угоду: неабходныя даны, сігнал успеху і тое, што выканаецца у разы частковага невясковасці. Такі спіс контроля дапамагае залічваць пазнейшыя змены ў кодзе чыста.
# Reproduce on your own machine
git clone https://github.com/manisuec/techinsights-tutorials
cd techinsights-tutorials/nodejs-test-runner
npm install
bash shared/bench.sh 5 # cold runs
WARM=1 bash shared/bench.sh 5 # warm runs
Рэальныя цыфры
Калі працюеце над стадзіяй «Рэальныя лікі», спачатку запісайце контракт: неабяжлівыя вхідныя даны, сігнал працэйскага успеху і тое, што выканаецца у разы ўзельнага неякшага рэзультата. Такі чарточка дапамагае заліцвачваць пазнейшыя змены ў кодзе. Дакументавайце як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія контралі і обработка некорэктных паведамленняў ёсць часткай продукту, а не элементамі пазнейшага дапрацоўвання. Спрыяйце эфектам як сінхронізацыі з зовнішнім светам, а не як замене вырахаваных значэнняў пад час адрасавання. Калі працюеце над стадзіяй «Рэальныя лікі», спачатку запісайце контракт: неабяжлівыя вхідныя даны, сігнал працэйскага успеху і тое, што выканаецца у разы ўзельнага неякшага рэзультата. Такі чарточка дапамагае заліцвачваць пазнейшыя змены ў кодзе. Спрыяйце гэтай стадзіі як контракту межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даўце назвы элементам, задайце крытэрыяі успеху і не прымайце мовчанкава часткова завершаныя рэзультаты.
=== node:test (Node v24.14.0) [cold] ===
run 1: 91 ms
run 2: 93 ms
run 3: 89 ms
run 4: 90 ms
run 5: 90 ms
median: 90 ms
=== Jest (30.4.1) [cold] ===
run 1: 817 ms
run 2: 689 ms
run 3: 718 ms
run 4: 711 ms
run 5: 685 ms
median: 711 ms
=== Vitest (4.1.11) [cold] ===
run 1: 548 ms
run 2: 648 ms
run 3: 534 ms
run 4: 531 ms
run 5: 535 ms
median: 535 ms
Матрыца функцый, 2026, пасляльнейшая перагледка
Матрыца фічаў 2026 года на пасляпэльнай стадыі працюе найкрашча, калі яе спрыяваць як вімерную паверхню. Запісайце адна ідэальная транскрыпцыю, адзін прыклад неудачы і прыметку па адвярненню перш чым расшырваць масштаб. Запісвайце часы выканання і косць токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Візуабельнасць косцаў з самага пачатку запобегае неспакою з боку расчыткаў, калі працэс пераходзіць з дэмаверсіі ў спяльныя сераўы. Стараюцца, каб праца з рэндэраванням заставалася дышучай, а дорогія працэсы вырахоўвання пераводзіце пасля вімеры за дапамою мемаізацыі. Недакладная мемаізацыя можа сховаць багі, вызваные застарэлымі данымі.
Калі выбіраць кожны з варыянтаў
Выбір наявнага этапу ўсё чытра ёст лепшы, калі яго розглядаць як віміроўваную велічыну. Зафіксавайце адна ідэальная транскрыпцыя, адзін прыклад неудачы і запіс пра відкатанне перш чым расшырваць масштабы. Зберагаюце конфігурацыю паза кодам прыкладнага програмы. Файлы сераўнавальных сэрвісаў, хранілішчы секрэтных даных і флагі функцый павінны знаходзіцца ў аднам месцы, куды аператары можаць аўдытуваць іх без неабяжнага чытання всіх дадзеных. Робіце працэс рэндараўцы дашчавым, а складныя вырахункі выканаць праз мемоізацыю толькі пасля віміроўвання. Неразумнае застосаванне мемоізацыі можа сховаць багі, вызваные застарэлымі дадзеннямі.
Міграцыя з Jest на Vitest за 30 хвілін
Пераход з Jest на stage найэфектывнейшы, калі яго спрыяюць памерныя показнікі. Зберагучы адна ідэальная транскрыпція, адзін случай неудачы і прыметкі па вярнэнню да пачатковага стану, спачатку трэба расшырыць сферу дзеяння. Неабяжна задокументаваць як успішны, так і варыянт вярнэння да нормальнага стану. Перапрыбуткі, людзкі контроль і обработка некорэктных паведамленняў ёсць часткай самага продукту, а не наступным етапам дорабкі. Старайцеся, каб праця з генераваннем дадзеных заставалася дышаўной, а складныя працэсы генеравання выконваліся толькі пасля памерэння ўплыву на продукт. Нечасавая мемаізацыя можа сховаць багі, зв’язаныя з застарэлымі дадзеннямі. Пераход з Jest на stage найэфектывнейшы, калі яго спрыяюць памерныя показнікі. Зберагучы адна ідэальная транскрыпція, адзін случай неудачы і прыметкі па вярнэнню да пачатковага стану, спачатку трэба расшырыць сферу дзеяння. Спрыяйце цэму этапу як кантракту межа вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Дайце назвы всім элементам, задаць крытэрыя успеху і не падзеўляйцеся на частковыя, некарэктныя рэзультаты.
# 1. Install
npm install -D vitest
# 2. Add a config (or piggyback on vite.config.ts if you have one)
# vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true, // makes describe/it/expect global
environment: 'jsdom', // or 'node' for backend
setupFiles: ['./tests/setup.ts'],
},
});
# 3. Swap imports, find/replace in your editor
# jest.mock → vi.mock
# jest.fn → vi.fn
# jest.spyOn → vi.spyOn
# require('@jest/globals') → require('vitest')
# jest.useFakeTimers() → vi.useFakeTimers()
# 4. Swap npm scripts
# "test": "jest" → "test": "vitest run"
# "test:watch": "jest --watch" → "test:watch": "vitest"
# 5. If you used babel-jest, delete it and babel.config.js
# 6. Run. Fix the 3-5 things that fail. Drink coffee.
Чаго не трэба робіць
Для тых элементаў, якія не будуць выкананы, паказваецца неабходнасць задаць вхідныя даны, адпаведальнага за крок і крытэрыя завершэння пры зміне коду. Аператары должны магчыма ўвайсці крок з вядомай точкі контролю, не прабуючы спадарожваць схованы стан. Запісвайце час выканання і вартасьць токенаў або запытак праза функцыйнае рэзультат. Відкрытыя даны пра вартасьці запобегаюць неспакоўным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя асяроддзя. Размешчайце стан разам з компонентам, які керуе змянамі. Калі усё храніцца ў глобальным сховішчы, багі, зв’язаныя з часам выканання, стаюць важкадоступнымі для адкрыцья.
Вывар
Для этапы вынесення вердыку неабходна пазначэнне вхідных дадзеных, адпаведнага власніка крока і крэтарыяў завершэння працы перад зменым коду. Аперацыйныя працавнікі должны магчымае перадзваначыць крок з вядомага пункта контролю, не прыпускаючы стану, які застаецца незрозумелым. Канфігурацыю трэба знаходзіць паза кодам прыемленае. Файлы серавэсу, хранільнікі секрэтных дадзеных і флагі функцыйяў должны быць аднароджаны ў аднам месца, якое працавнікі можуць пераглядаць, не чытаючы весь структураны код. Стан трэба размешчаць разам з компонентам, які керуея мутацыяй. Размешчэнне всего ў глобальным хранільніку ускладняе выяўленне багоў, зв’язаных з часам адпаведных дзеянь.
Дапаможны матэрыял: як чытаць ціфры ў гэтым артыкуле
У Дадатку паказана спосаб гледзення на стадыю, неабяцковыя даныя, адміністратар шагу і крэтыяры выходу пры зміне коду. Аператары должны магчымаць перзапуск шагу з вядомай точкі контролю без адгадвання захаванага стану. Неабяцковы пат і пат вярнення трэба задокументаваць разам. Перапрыяты, людзкія контралі і обработка некорэктных паведамленняў ёсць часткай продукту, а не пасляднім дапрацоўкам. Стан трэба размешчаць разам з компонентам, які керуе мутацыяй. Перанесенне усяго у глобальны хранільнік ускладняе выяўленне багоў з часам. У Дадатку паказана спосаб гледзення на стадыю, неабяцковыя даныя, адміністратар шагу і крэтыяры выходу пры зміне коду. Аператары должны магчымаць перзапуск шагу з вядомай точкі контролю без адгадвання захаванага стану. Спрыяць гэтай этапы як кантракту межа неабяцковымі данымі і перакананымі выходамі. Даць назву артыфактам, задаць перакананні на успех і адмовіцца ад тыхоўкага частковага завершэння.
Чэк-ліст аператыўнай працы
Калі працуеце над стадзіяй чэк-ліста аператыўнай працы, спачатку запісуйце умовы контракту: неабходныя даныя, сігнал успеху і тое, што выканаецца у разы ўзельнага неяксамоства. Такі чэк-ліст дапамагае заставіць пазнейшыя змены коду быць чыстымі.
Валідзіце маленькія, тэставаныя елементы замест абмежлёных скрыптав. Калі якісь крок не выйшае, неяксамоства павінны адносіцца да адной відповядачнасці, а не да заплутанага ланцуга задач.
Расследвуйце эфекты як сінхронізацыю з зовнішнім светам, а не як замену значэнняў, вырахаваных пад час адрасавання.
Фіксуйце версіі залежнасцяў і запісвайце хеш-значэнне зображэння, якое было выкарыстоўванае пад час дэманстрацыі. Возможнасць павтарэння важлівей, чым традыцыйныя знання.
Расследвуйце гэтую стадзію як контракт межа данымі і перакананымі выходнымі рэзультатамі. Даўайце назвы элементам, задаюце крытэрыя успеху і адмовляйцеся ад мовчанкавага частковага завершэння.
Спрытваець эфекты як сінхронізацыю з зовнішнім светам, а не як замену для вырахаваных значэнняў пад час адрасавання.
Перш чым пераходзіць да наступнага кроку, заморозьце версіі, зафіксуйце «золаты» транскрыпты для крытычнага шляху і паказвайце способы вярнення да пачатковага стану. У спільных срэдах неабходны ліміты частоты запытоў, перакананні ў правах на вікорыстоўвання рэсурсаў і чысткі власнік для змены секрэтных даных. Валіце надзейнасць працы над красавімі, але разовымі дэманстрацыямі.
Прыметка для b78b143fb7a9: не кладзіце ключы прадастаўцаў у рэпазітарый, задайце ліміт токена на кожную сесію і зберагайце транскрыпты разам з фіксатрамі для адрасавання, каб пазнейшыя замены модэляў заставаліся порównанневымі.