콘텐츠로 이동

테스트: Jest

출처 URL: https://nextjs.org/docs/pages/guides/testing/jest

마지막 업데이트: 2026년 2월 20일

Jest와 React Testing Library는 단위 테스트스냅샷 테스트에 자주 함께 사용됩니다. 이 가이드는 Next.js와 Jest를 설정하고 첫 번째 테스트를 작성하는 방법을 보여줍니다.

알아두면 좋아요: async 서버 컴포넌트는 React 생태계에서 새로워서, 현재 Jest는 이를 지원하지 않습니다. 동기 서버 및 클라이언트 컴포넌트에 대해서는 단위 테스트를 계속 실행할 수 있지만, async 컴포넌트에는 E2E 테스트를 권장합니다.

create-next-app과 Next.js with-jest 예제를 사용하면 빠르게 시작할 수 있습니다:

pnpmnpmyarnbun

터미널

pnpm create next-app --example with-jest with-jest-app

Next.js 12 릴리스 이후 Next.js는 Jest를 위한 기본 구성을 제공합니다.

Jest를 설정하려면 jest와 다음 패키지를 devDependencies로 설치하세요:

pnpmnpmyarnbun

터미널

pnpm add -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest

다음 명령으로 기본 Jest 구성 파일을 생성하세요:

pnpmnpmyarnbun

터미널

pnpm create jest@latest

이 작업은 Jest 설정을 위한 일련의 프롬프트를 안내하며, jest.config.ts|js 파일도 자동으로 생성합니다.

구성 파일을 next/jest를 사용하도록 업데이트하세요. 이 트랜스포머에는 Jest가 Next.js와 함께 작동하는 데 필요한 모든 구성 옵션이 포함되어 있습니다:

jest.config.ts

JavaScriptTypeScript

import type { Config } from 'jest'
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})
// Add any custom config to be passed to Jest
const config: Config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)

내부적으로 next/jest는 다음을 포함해 Jest 구성을 자동으로 처리합니다:

  • Next.js Compiler를 사용하는 transform 설정
  • 스타일시트(.css, .module.css, 및 scss 변형), 이미지 import, next/font 자동 모킹
  • .env(모든 변형 포함)을 process.env에 로드
  • 테스트 해석 및 트랜스폼에서 node_modules 무시
  • 테스트 해석에서 .next 무시
  • SWC 트랜스폼을 활성화하는 플래그를 위해 next.config.js 로딩

알아두면 좋아요: 환경 변수를 직접 테스트하려면 별도의 설정 스크립트나 jest.config.ts 파일에서 수동으로 로드하세요. 자세한 내용은 Test Environment Variables를 참고하세요.

Next.js Compiler를 사용하지 않고 Babel을 선택하면, 위 패키지 외에 babel-jestidentity-obj-proxy를 설치하고 Jest를 수동으로 구성해야 합니다.

Next.js용 Jest 구성에 권장되는 옵션은 다음과 같습니다:

jest.config.js

module.exports = {
collectCoverage: true,
// on node 14.x coverage provider v8 offers good speed and more or less good report
coverageProvider: 'v8',
collectCoverageFrom: [
'**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
'!<rootDir>/out/**',
'!<rootDir>/.next/**',
'!<rootDir>/*.config.js',
'!<rootDir>/coverage/**',
],
moduleNameMapper: {
// Handle CSS imports (with CSS modules)
// https://jestjs.io/docs/webpack#mocking-css-modules
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
// Handle CSS imports (without CSS modules)
'^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
// Handle image imports
// https://jestjs.io/docs/webpack#handling-static-assets
'^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$': `<rootDir>/__mocks__/fileMock.js`,
// Handle module aliases
'^@/components/(.*)$': '<rootDir>/components/$1',
// Handle @next/font
'@next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
// Handle next/font
'next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
// Disable server-only
'server-only': `<rootDir>/__mocks__/empty.js`,
},
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
testEnvironment: 'jsdom',
transform: {
// Use babel-jest to transpile tests with the next/babel preset
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
},
transformIgnorePatterns: [
'/node_modules/',
'^.+\\.module\\.(css|sass|scss)$',
],
}

각 구성 옵션에 대한 자세한 내용은 Jest 문서를 참고하세요. 또한 Next.js가 Jest를 어떻게 구성하는지 확인하려면 next/jest 구성을 검토하는 것이 좋습니다.

스타일시트 및 이미지 import 처리

섹션 제목: “스타일시트 및 이미지 import 처리”

스타일시트와 이미지는 테스트에서 사용되지 않지만 import하면 오류를 유발할 수 있으므로 모킹해야 합니다.

위 구성에서 참조한 fileMock.jsstyleMock.js 모크 파일을 __mocks__ 디렉터리 안에 만드세요:

mocks/fileMock.js

module.exports = 'test-file-stub'

mocks/styleMock.js

module.exports = {}

정적 에셋 처리에 대한 자세한 내용은 Jest 문서를 참고하세요.

폰트를 처리하려면 __mocks__ 디렉터리에 nextFontMock.js 파일을 만들고 다음 구성을 추가하세요:

mocks/nextFontMock.js

module.exports = new Proxy(
{},
{
get: function getter() {
return () => ({
className: 'className',
variable: 'variable',
style: { fontFamily: 'fontFamily' },
})
},
}
)

선택 사항: 절대 import 및 모듈 경로 별칭 처리

섹션 제목: “선택 사항: 절대 import 및 모듈 경로 별칭 처리”

프로젝트에서 모듈 경로 별칭을 사용한다면, jsconfig.json의 paths 옵션과 jest.config.jsmoduleNameMapper 옵션을 일치시켜 Jest가 import를 해석하도록 구성해야 합니다. 예:

tsconfig.json 또는 jsconfig.json

{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"@/components/*": ["components/*"]
}
}
}

jest.config.js

moduleNameMapper: {
// ...
'^@/components/(.*)$': '<rootDir>/components/$1',
}

선택 사항: Jest를 사용자 정의 matcher로 확장

섹션 제목: “선택 사항: Jest를 사용자 정의 matcher로 확장”

@testing-library/jest-dom에는 .toBeInTheDocument()와 같은 편리한 사용자 정의 matcher가 포함되어 있어 테스트 작성이 쉬워집니다. 다음 옵션을 Jest 구성 파일에 추가하여 모든 테스트에서 사용자 정의 matcher를 가져올 수 있습니다:

jest.config.ts

JavaScriptTypeScript

setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']

그런 다음 jest.setup 내부에 다음 import를 추가하세요:

jest.setup.ts

JavaScriptTypeScript

import '@testing-library/jest-dom'

알아두면 좋아요: extend-expectv6.0에서 제거되었습니다. 따라서 @testing-library/jest-dom 6 이전 버전을 사용하는 경우 @testing-library/jest-dom/extend-expect를 대신 import해야 합니다.

각 테스트 전에 추가 설정 옵션이 필요하면 위의 jest.setup 파일에 추가할 수 있습니다.

package.json에 테스트 스크립트 추가

섹션 제목: “package.json에 테스트 스크립트 추가”

마지막으로 package.json 파일에 Jest test 스크립트를 추가하세요:

package.json

{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest",
"test:watch": "jest --watch"
}
}

jest --watch는 파일이 변경될 때 테스트를 다시 실행합니다. 더 많은 Jest CLI 옵션은 Jest 문서를 참고하세요.

이제 프로젝트에서 테스트를 실행할 준비가 되었습니다. 프로젝트 루트 디렉터리에 __tests__ 폴더를 만드세요.

예를 들어 <Home /> 컴포넌트가 헤딩을 성공적으로 렌더링하는지 확인하는 테스트를 추가할 수 있습니다:

export default function Home() {
return <h1>Home</h1>
}

tests/index.test.js

import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'
describe('Home', () => {
it('renders a heading', () => {
render(<Home />)
const heading = screen.getByRole('heading', { level: 1 })
expect(heading).toBeInTheDocument()
})
})

선택적으로, 컴포넌트의 예기치 않은 변화를 추적하기 위해 스냅샷 테스트를 추가하세요:

tests/snapshot.js

import { render } from '@testing-library/react'
import Home from '../pages/index'
it('renders homepage unchanged', () => {
const { container } = render(<Home />)
expect(container).toMatchSnapshot()
})

알아두면 좋아요: 페이지 라우터 내부의 파일은 모두 라우트로 간주되므로, 테스트 파일을 페이지 라우터 안에 포함하지 마세요.

그런 다음 다음 명령을 실행해 테스트를 실행하세요:

pnpmnpmyarnbun

터미널

pnpm test

추가로 참고할 만한 자료는 다음과 같습니다:

보내기