Coding Archive

[next.js & jest] Jest ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ ๊ฐ€์ด๋“œ: Next.js + TypeScript ํ™˜๊ฒฝ์—์„œ์˜ Jest ์‚ฌ์šฉ๋ฒ• ๋ณธ๋ฌธ

๐Ÿ’ป Programming/Next.js & project

[next.js & jest] Jest ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ ๊ฐ€์ด๋“œ: Next.js + TypeScript ํ™˜๊ฒฝ์—์„œ์˜ Jest ์‚ฌ์šฉ๋ฒ•

์ฝ”๋“ฑ์–ด 2024. 10. 22. 22:09

 


Jest ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ ๊ฐ€์ด๋“œ: Next.js + TypeScript ํ™˜๊ฒฝ์—์„œ์˜ Jest ์‚ฌ์šฉ๋ฒ•

 

์ด๋ฒˆ์—๋Š” Next.js์™€ TypeScript ํ”„๋กœ์ ํŠธ์—์„œ Jest๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Jest๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ๊ณผ ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ๋น ๋ฅด๊ณ  ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

 

1. Jest ์„ค์น˜

Step 1: Jest ํŒจํ‚ค์ง€ ์„ค์น˜

๋จผ์ €, Jest์™€ TypeScript ํ™˜๊ฒฝ์—์„œ Jest๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

yarn add jest ts-jest jest-environment-jsdom @types/jest @testing-library/react @testing-library/jest-dom @testing-library/dom --dev
 
  • jest: Jest์˜ ํ•ต์‹ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ts-jest: TypeScript๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Jest ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํŒจํ‚ค์ง€.
  • @types/jest: Jest์˜ ํƒ€์ž… ์ •์˜ ํŒŒ์ผ๋กœ, TypeScript ํ”„๋กœ์ ํŠธ์—์„œ Jest์˜ ํƒ€์ž…์„ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ.
  • jest-environment-jsdom: DOM ํ™˜๊ฒฝ์—์„œ Jest ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํŒจํ‚ค์ง€.
  • @types/jest: Jest์˜ ํƒ€์ž… ์ •์˜ ํŒŒ์ผ๋กœ, TypeScript์—์„œ Jest๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํƒ€์ž… ์ง€์›์„ ์ œ๊ณต.
  • @testing-library/react: React ์ปดํฌ๋„ŒํŠธ์˜ UI๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ. ์‚ฌ์šฉ์ž ๊ด€์ ์—์„œ UI๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์คŒ.
  • @testing-library/jest-dom: Jest์—์„œ DOM ๊ด€๋ จ ๋งค์ฒ˜(์˜ˆ: toBeInTheDocument() ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์คŒ.
  • @testing-library/dom: DOM ์กฐ์ž‘์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋ฅผ ์ œ๊ณต.

2. Jest ๊ธฐ๋ณธ ์„ค์ •

Step 2: Jest ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ

Next.js ํ”„๋กœ์ ํŠธ์—์„œ Jest๋ฅผ ์„ค์ •ํ•˜๋ ค๋ฉด jest.config.js ํŒŒ์ผ๊ณผ jest.setup.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

/* jest.setup.js */

import '@testing-library/jest-dom' // React Testing Library์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์„ค์ •
/* jest.config.cjs */

const nextJest = require('next/jest'); // Next.js ํ”„๋กœ์ ํŠธ์—์„œ Jest๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํ•จ์ˆ˜ 

const createJestConfig = nextJest({ 
    dir: './', // Next.js ์•ฑ์˜ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ •
}); 

const customJestConfig = { 
    testEnvironment: 'jest-environment-jsdom', // DOM ํ™˜๊ฒฝ์—์„œ ํ…Œ์ŠคํŠธ 
    setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], // ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์„ค์ • ํŒŒ์ผ 
    moduleNameMapper: { 
    	'^@/(.*)$': '<rootDir>/src/$1', // ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒฝ๋กœ ๋งคํ•‘  
    }, 
    transform: { 
    	'^.+\\.(ts|tsx)$': 'ts-jest', // TypeScript ํŒŒ์ผ์„ Jest๊ฐ€ ์ธ์‹ํ•˜๋„๋ก ์„ค์ • 
    }, 
}; 

module.exports = createJestConfig(customJestConfig);โ€‹

3. ํด๋” ๊ตฌ์กฐ

ํ”„๋กœ์ ํŠธ ๋‚ด์˜ ํ…Œ์ŠคํŠธ ํŒŒ์ผ๋“ค์€ ์ผ๋ฐ˜์ ์œผ๋กœ __tests__ ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์— .test.tsx ๋˜๋Š” .spec.ts ํŒŒ์ผ ํ˜•์‹์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

/project-root 
โ”œโ”€โ”€ /src 
โ”‚ โ”œโ”€โ”€ /app 
โ”‚ โ”‚ โ””โ”€โ”€ login.tsx 
โ”‚ โ”œโ”€โ”€ /components 
โ”‚ โ”‚ โ””โ”€โ”€ Header.tsx 
โ”‚ โ”œโ”€โ”€ /__tests__ 
โ”‚ โ”‚ โ””โ”€โ”€ login.test.tsx
โ”œโ”€โ”€ jest.config.js 
โ”œโ”€โ”€ jest.setup.js 
โ”œโ”€โ”€ tsconfig.json 
โ””โ”€โ”€ package.json
  • __tests__: ํ…Œ์ŠคํŠธ ํŒŒ์ผ๋“ค์„ ๋ชจ์•„ ๋†“๋Š” ํด๋”์ž…๋‹ˆ๋‹ค. ์ด ํด๋”์— *.test.tsx ๋˜๋Š” *.spec.ts ํŒŒ์ผ๋“ค์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ ํŒŒ์ผ์€ ํ”„๋กœ๋•์…˜ ํŒŒ์ผ๊ณผ ๋™์ผํ•œ ๊ฒฝ๋กœ์— ์œ„์น˜ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๋ณ„๋„์˜ __tests__ ํด๋”์— ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.


4. TypeScript ์„ค์ •๊ณผ Jest ํ†ตํ•ฉ

Step 3: TypeScript ์„ค์ • ํŒŒ์ผ(tsconfig.json) ์—…๋ฐ์ดํŠธ

Jest์™€ TypeScript์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด tsconfig.json ํŒŒ์ผ์— Jest์™€ ๊ด€๋ จ๋œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

{ 
    "compilerOptions": { 
        "types": ["node", "jest", "@testing-library/jest-dom"],
        "lib": ["dom", "dom.iterable", "esnext"], 
        "module": "esnext", 
        "moduleResolution": "bundler", 
        "jsx": "preserve", 
        "skipLibCheck": true, 
        "esModuleInterop": true 
        ...
    },
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "__tests__/**/*.ts", "__tests__/**/*.tsx"], 
    "exclude": ["node_modules"] 
}
  • types: Jest์™€ Node.js์˜ ํƒ€์ž…์„ ํฌํ•จํ•˜์—ฌ Jest ํ™˜๊ฒฝ์—์„œ TypeScript ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • include: Jest ํ…Œ์ŠคํŠธ ํŒŒ์ผ(__tests__ ํด๋”๋‚˜ *.test.sx, *.test.tsx ํŒŒ์ผ)์„ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค.


5. Jest ์‹คํ–‰

Step 4: ํ…Œ์ŠคํŠธ ์‹คํ–‰

์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉด package.json์— ์•„๋ž˜์™€ ๊ฐ™์ด Jest ์‹คํ–‰ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

{ 
    "scripts": { 
        ...
        "test": "jest",
        "test:watch": "jest --watch" // ํŒŒ์ผ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰
        ...
    } 
}

 

์ดํ›„ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋Š” ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

yarn test

 

Comments