TechFeedTechFeed
Programming Languages

노드 테스트, 어서트, 커버리지, 크론 스크립트 | 제스트를 또 설치해야 할까?

크론과 발행 게이트 스크립트는 제스트를 또 깔지 않고 노드 테스트 모듈로 돈다. node --test가 이름 규칙 파일을 찾고, 어서트는 내장 엄격 모듈이다. 커버리지는 실험 플래그다. 개발자, Next.js, 백엔드, API, 깃허브, 타입스크립트, 노드 기준으로 스크립트 칸만 보고 비테스트 이전 글과 자리를 섞지 않는다. 2026년 8월 공식 문서.

by

검증 스크립트 한 파일을 고칠 때마다 제스트를 또 깔 필요는 없습니다. 노드 18에 들어온 테스트 모듈은 20에서 안정이 됐고, node --test 한 줄이 이름 규칙을 맞춘 파일을 찾습니다. 어서트는 내장 엄격 모듈입니다. 커버리지와 워치는 아직 실험이라, 머지 조건에는 종료 코드만 둡니다. 서브테스트는 await로 닫지 않으면 실패입니다. 저는 12개 사이트 발행 게이트의 날짜 헬퍼를 그 칸에서만 돌립니다. 화면 클릭은 플레이라이트 글에, 비테스트로 옮기는 시점은 비교 글에 있습니다. 여기는 크론과 검수 스크립트만 봅니다.


숫자는 2026년 8월 노드 테스트 러너 문서와 어서트 문서 기준입니다.


패키지 없이 스크립트를 검사하는 자리

노드 20부터 테스트 모듈은 안정입니다. 파일 하나와 어서트만 있으면 됩니다. 제스트 설정 파일은 두지 않습니다.


공식 문서는 모듈 이름이 node:test라고 적습니다. 스키마 없이 test만 적으면 못 찾습니다. 18.0.0과 16.17.0에 들어왔고, 20.0.0에서 안정으로 올랐습니다. 실패가 하나라도 있으면 프로세스 종료 코드는 1입니다. 크론이 그 숫자를 보면 됩니다.


어서트는 node:assert/strict를 씁니다. 느슨한 같음은 테스트에서 빼는 편이 짧습니다. 던지면 실패, 프로미스가 거절되면 실패, 콜백 첫 인자가 참이면 실패입니다. 세 갈래가 문서 맨 위에 있습니다.


항목노드 테스트제스트비테스트
설치없음. 런타임에 포함패키지와 설정 파일패키지. 바이트 설정과 묶음
실행node --test제스트 명령비테스트 명령
어서트내장 엄격 모듈익스펙트익스펙트, 차이 호환
잘 맞는 자리크론, 발행 게이트, 날짜 헬퍼옛 웹팩 앱, 스냅샷이 많은 레거시Vite 앱, 리액트 컴포넌트
이 글에서 안 보는 칸돔 렌더이전 체크리스트핸들러 모킹

비테스트와 제스트를 언제 옮길지는 비교 글입니다. API 핸들러 가짜는 모킹 글입니다. 오늘은 설치 칸이 없는 스크립트만 봅니다.


날짜 헬퍼를 내장 러너로 검사
'use strict' const { test } = require('node:test') const assert = require('node:assert/strict') function nowKSTdate() { return new Date() .toLocaleString('sv-SE', { timeZone: 'Asia/Seoul' }) .slice(0, 10) } test('한국 표준시 날짜는 하이픈 열 글자', () => { const s = nowKSTdate() assert.equal(s.length, 10) assert.match(s, /^\d{4}-\d{2}-\d{2}$/) assert.equal(s.endsWith('Z'), false) })

빠른 갈래 | 순수 함수와 종료 코드만 보면 내장 러너입니다. 컴포넌트 렌더는 비테스트, 실제 클릭은 플레이라이트입니다. 세 칸을 한 설정에 섞지 않습니다.


파일 이름 여섯 가지가 자동으로 잡힌다

*.test.js, *-test.js, *_test.js, test-*.js, test.js, test/ 아래가 기본입니다. 타입 스트리핑을 끄지 않으면 ts 같은 확장도 붙습니다.


명령은 node --test입니다. 인자를 안 주면 위 여섯 패턴을 재귀로 찾습니다. 글롭을 직접 넘기면 그 목록만 돕니다. 셸이 별표를 먼저 펼치지 않게 따옴표를 감쌉니다. 문서 예는 node --test "**/*.test.js" "**/*.spec.js"입니다. 스펙 접미사는 기본 목록에 없어서, 쓰려면 인자가 필요합니다.


격리 기본값은 파일마다 자식 프로세스입니다. 동시에 몇 개를 열지는 --test-concurrency입니다. 격리를 끄면 한 프로세스에 파일이 같이 올라가서, 전역 값이 옆 파일을 건드릴 수 있습니다. 발행 게이트처럼 날짜 함수가 순수하면 기본값으로 둡니다.


패턴기본 탐색
**/*.test.jsscripts/kst.test.js
**/*-test.jsscripts/kst-test.js
**/*_test.jsscripts/kst_test.js
**/test-*.jsscripts/test-kst.js
**/test.jsscripts/test.js
**/test/**/*.jstest/kst.js
**/*.spec.jsscripts/kst.spec.js아니오. 글롭 인자 필요

타입스크립트 파일은 --no-strip-types를 안 켠 때만 같은 이름 규칙으로 붙습니다. 이넘과 생성자 공개 인자는 런타임이 거부합니다. 그 칸은 타입 스트리핑 글입니다. 노드 버전을 클론마다 맞추는 칸은 미즈 글입니다.


기본 탐색과 글롭을 나눠 실행
node --test node --test "scripts/**/*.test.js" node --test --test-name-pattern="한국 표준시" node --test --watch
노드 테스트 러너가 기본으로 찾는 파일 이름 여섯 가지와 spec 접미사 예외
기본 여섯 패턴만 자동이다. spec 접미사는 글롭 인자를 따로 넘긴다

서브테스트를 기다리지 않으면 실패로 찍힌다

t.test는 부모가 끝나기 전에 마쳐야 합니다. await를 빼면 남은 자식은 취소되고 실패입니다. describe 안의 it은 스위트가 기다려 줍니다.


문서 서브테스트 칸이 그 순서를 못 박습니다. 상위 test 콜백이 비동기가 아니면, 자식이 끝나기 전에 결과가 먼저 나갑니다. 늦게 만든 자식은 실패로 보고됩니다. 테스트가 끝난 뒤 setImmediate에서 또 자식을 열면 같은 실패입니다.


describeit은 스위트와 테스트의 별명입니다. 형제 it은 큐에 같이 올라가서, 랜덤 순서를 켜도 섞일 수 있습니다. 반대로 루프 안에서 await t.test를 하나씩 기다리면 선언 순서가 유지됩니다. 랜덤 플래그는 2026년 문서에서 아직 초기 개발입니다. 워치 모드와는 같이 못 씁니다.


서브테스트는 await로 닫는다
'use strict' const { test } = require('node:test') const assert = require('node:assert/strict') test('슬러그 헬퍼', async (t) => { const toSlug = (s) => String(s) .trim() .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-|-$/g, '') await t.test('공백을 하이픈으로', () => { assert.equal(toSlug('Hello World'), 'hello-world') }) await t.test('양끝 하이픈을 지움', () => { assert.equal(toSlug('--ok--'), 'ok') }) })

이름 필터는 --test-name-pattern입니다. 자바스크립트 정규식이고, 여러 번 넘길 수 있습니다. 부모 이름이 안 맞으면 자식도 안 돕니다. 스킵은 skip: true 또는 t.skip()입니다. 할 일은 todo: true로 표시하면 실행은 하되 종료 코드를 안 올립니다. 둘을 같이 주면 스킵이 이깁니다.


모킹은 mock.fnt.mock.method입니다. 테스트 컨텍스트에서 열면 끝난 뒤 자동으로 되돌립니다. 타이머는 t.mock.timers.enable 뒤에 tick으로 시간을 밀면 됩니다. 전역 mock.reset은 직접 호출한 자리만 지웁니다.


자식은 부모가 살아 있을 때만 | 상위 테스트가 먼저 반환하면 남은 서브테스트는 실패입니다. 비동기 콜백이면 꼭 await를 붙입니다. describe 스위트는 이 함정이 덜합니다.


서브테스트를 await하지 않으면 부모가 먼저 끝나 자식이 실패로 찍히는 흐름
t.test 자식은 부모가 끝나기 전에 마친다. 빼면 취소 후 실패다

컴포넌트 테스트는 여기 자리가 아니다

돔과 리액트 렌더는 비테스트 칸입니다. 브라우저 클릭은 플레이라이트입니다. 내장 러너는 순수 함수와 스크립트 출구 코드만 봅니다.


문의 버튼을 두 번 누르는 화면은 폼 상태 훅 글과 플레이라이트 글입니다. 컴포넌트를 돔 환경에 올리는 설정을 내장 러너에 억지로 붙이면, 변환과 경로 별칭을 직접 적게 됩니다. 노드는 테스트 파일이 일반 스크립트처럼 실행된다고 적습니다. Vite가 해 주던 변환은 없습니다.


번 런타임 테스트는 또 다른 실행기입니다. 설치 속도 비교는 번과 노드 글입니다. 여기는 노드 프로세스의 테스트 플래그만 봅니다. 파이썬 쪽 검사 칸은 파이라이트 글과 자리를 나눕니다.


카카오 콜백 서명 검증처럼 비밀키와 본문만 다루는 함수는 내장 러너가 짧습니다. 넥스트 페이지를 실제로 여는 검사는 여기 자리가 아닙니다. 그 칸은 플레이라이트가 브라우저를 띄웁니다.


깃허브 액션에서 스크립트 테스트만 실행
name: script-test on: pull_request: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 24 - run: node --test "scripts/**/*.test.js"

패키지 설치 단계가 빠집니다. 스크립트가 내장 모듈만 쓰면 npm ci도 생략할 수 있습니다. 의존성이 있는 헬퍼면 설치를 한 줄 넣습니다. 장기 클라우드 키를 시크릿에 두지 않는 순서는 액션 OIDC 글입니다. 이 워크플로는 테스트 한 줄만 보여 줍니다.


리포터 기본값은 스펙입니다. 23부터는 화면이 아닌 출력에서도 스펙이 기본입니다. 탭과 점은 플래그로 바꿉니다. 여러 리포터를 동시에 열고 파일로 보낼 수 있습니다. 커버리지용 lcov는 결과 줄이 없어서, 스펙과 같이 두는 편이 문서 권고입니다.


커버리지는 아직 실험 플래그다

--experimental-test-coverage는 안정이 아닙니다. 스펙 리포터에 요약이 붙고, lcov 파일은 따로 찍습니다. 게이트 숫자로 쓰기 전에 문서 안정 칸을 다시 봅니다.


2026년 8월 노드 26 문서는 커버리지 칸에 안정 지수 1, 실험이라고 적습니다. 워치 모드도 실험입니다. 스냅샷 비교는 23.4.0부터 실험이 아닙니다. t.assert.snapshot으로 값을 남기고, 갱신은 --test-update-snapshots입니다. 파일 기본 이름은 테스트 파일에 .snapshot을 붙인 것입니다.


커버리지를 켜면 코어 모듈과 node_modules는 기본으로 빠집니다. 넣으려면 include 플래그, 빼려면 exclude 플래그입니다. 줄 단위로 끄려면 주석 node:coverage disableenable입니다. 다음 한 줄만 무시할 때는 ignore next입니다.


실패만 다시 돌리는 플래그는 --test-rerun-failures입니다. 상태 파일 경로를 넘기면, 아직 통과하지 않은 테스트만 남깁니다. 순서가 바뀌거나 줄 번호가 밀리면 이전 통과로 오인할 수 있다고 문서가 적습니다. 결정적 순서일 때만 씁니다.


실험 커버리지와 스펙 리포터를 같이
node --test --experimental-test-coverage \ --test-reporter=spec --test-reporter-destination=stdout \ --test-reporter=lcov --test-reporter-destination=lcov.info \ "scripts/**/*.test.js"
안정인 테스트 모듈과 아직 실험인 커버리지, 워치 모드를 나눈 표
러너 본체는 안정이다. 커버리지와 워치는 2026년 8월에도 실험 플래그다

게이트에 넣을 숫자 | 종료 코드 1은 안정 칸입니다. 커버리지 퍼센트는 실험 칸입니다. 머지 조건에는 종료 코드만 넣고, 퍼센트는 로컬 확인용으로 둡니다.


참고 자료


플래그 이름과 안정 지수는 쓰는 노드 마이너가 우선입니다. 위 표는 2026년 8월 공개 문서 기준입니다.


자주 묻는 질문

넥스트 앱 테스트도 이걸로 되나?

페이지와 컴포넌트는 비테스트나 플레이라이트가 맞습니다. 내장 러너는 변환과 돔 환경을 기본으로 안 엽니다. 날짜 헬퍼, 슬러그, 서명 검증처럼 순수 함수만 여기 둡니다.


제스트 설정을 지금 지워야 하나?

컴포넌트 스냅샷과 돔 테스트가 남아 있으면 유지합니다. 크론 스크립트만 늘고 있으면 그 폴더만 node --test로 뺍니다. 한 저장소에 러너 두 개가 있어도, 폴더를 나누면 충돌이 적습니다.


ts 테스트 파일은 바로 도나?

타입 스트리핑이 켜진 노드에서는 이름 규칙만 맞으면 돕니다. 이넘과 생성자 공개 인자는 거부됩니다. 검사는 tsc --noEmit을 따로 둡니다. 실행과 검사는 한 명령이 아닙니다.


커버리지 숫자를 머지 조건에 넣나?

2026년 8월 문서는 실험이라고 적습니다. 종료 코드 1만 게이트에 넣고, 퍼센트는 로컬 확인용입니다. 안정으로 올라간 뒤에 숫자를 옮깁니다.


워치 모드로 저장할 때마다 돌리나?

node --test --watch가 그 자리입니다. 안정 지수는 실험입니다. 의존 파일이 바뀌면 영향 받은 테스트만 다시 돕니다. 랜덤 순서 플래그와는 같이 못 씁니다.


카카오 서명 검증을 여기에 두나?

비밀키와 본문 문자열만 비교하는 함수면 둡니다. 콘솔에 주소를 넣는 터널과, 브라우저에서 콜백을 누르는 흐름은 다른 글입니다. 함수 입출력만 어서트로 고정합니다.


노드 테스트어서트커버리지크론node:test제스트비테스트개발자Next.js백엔드API깃허브타입스크립트노드

함께 보면 좋은 문제 해결

EXPLORE / Programming Languages

이어서 읽어보기

전체 토픽 둘러보기