Node.js 24 LTS에서 달라진 native test runner 활용기

배경

프로젝트에서 사용하던 jest가 ESM 환경에서 계속 문제를 일으켰다. Node.js 24가 LTS로 승격되면서 native test runner도 안정화됐다는 소식에 전환을 결정했다.

마이그레이션 과정

기본 구조 변경

jest의 describe/it 대신 node의 test를 사용한다.

import { test, describe } from 'node:test';
import assert from 'node:assert';

describe('User Service', () => {
  test('should create user', async () => {
    const user = await createUser({ name: 'test' });
    assert.strictEqual(user.name, 'test');
  });
});

Mock 처리

jest.fn() 대신 mock 모듈을 사용한다.

import { mock } from 'node:test';

const mockFn = mock.fn(() => 'mocked');
await someFunction(mockFn);

assert.strictEqual(mockFn.mock.calls.length, 1);

실행 속도

약 1200개 테스트 기준으로 jest는 45초, native runner는 28초 정도 소요됐다. cold start도 확연히 빨라졌다.

마주친 문제들

1. Assertion 라이브러리

jest의 expect에 익숙해서 처음엔 불편했다. node:assert/strict를 사용하니 해결됐다.

2. Coverage 리포트

--experimental-test-coverage 플래그로 가능하지만 jest만큼 상세하진 않다. 일단은 c8을 병행했다.

3. Setup/Teardown

beforeEach, afterEach는 동일하게 동작한다. 글로벌 setup은 별도 파일로 분리해서 --require 옵션으로 처리했다.

결론

의존성 하나가 줄고 실행 속도도 개선돼서 만족스럽다. 아직은 ecosystem이 jest보다 약하지만, LTS가 된 만큼 앞으로 개선될 것으로 보인다. 새 프로젝트에선 고민 없이 native runner를 쓸 것 같다.