Практычныя прытамулі: Натывны ўпрынцап тэстаў у Node протыку Jest пратыку Vitest: адна сутка, трое
Практычныя прыказкі: Адгэнны працоўны календар для теставання у Node – протыяўставленне Jest і Vitest; адна пакетная система, тры спосабы теставання: контракты, пераказы і можлівасць дадзення коду для команд, якія выкарыстоўваюць гэты патэрн.
Існавайце гэта як перапрацоўку ідэй з артыкула “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анневымі.