Галоўная / Артыкулы / Практычныя прытамулі: Натывны ўпрынцап тэстаў у Node протыку Jest пратыку Vitest: адна сутка, трое

Практычныя прытамулі: Натывны ўпрынцап тэстаў у Node протыку Jest пратыку Vitest: адна сутка, трое

Практычныя прыказкі: Адгэнны працоўны календар для теставання у Node – протыяўставленне Jest і Vitest; адна пакетная система, тры спосабы теставання: контракты, пераказы і можлівасць дадзення коду для команд, якія выкарыстоўваюць гэты патэрн.

2126 слоў

Існавайце гэта як перапрацоўку ідэй з артыкула “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анневымі.