말로만 하던 TDD를 해보려고 함.
React Testing Library는 Behavior Driven Test(행위 주도 테스트) 방법론이 대두 되면서 함께 주목 받기 시작한 테스팅 라이브러리 입니다. 행위 주도 테스트는 기존에 관행이던 Implementation Driven Test(구현 주도 테스트)의 단점을 보완하기 위한 방법론인데요.
Implementation Driven Test에서는 주로 애플리케이션이 어떻게 작동하는지에 대해서 초점을 두어 테스트를 작성합니다.
Behavior Driven Test에서는 사용자가 애플리케이션을 이용하는 관점에서 사용자의 실제 경험 위주로 테스트를 작성합니다.
// nextjs에 jest 설치
yarn add --dev jest
yarn add --dev jest-environment-jsdom
yarn add --dev @babel/preset-typescript
// @types/jest 패키지를 깔면 import하지 않아도 사용할 수 있다.
yarn add --dev @types/jest
// 라이브러리 설치
yarn add --dev @testing-library/react
yarn add --dev @testing-library/jest-dom
Under the hood, next/jest is automatically configuring Jest for you, including:
- Setting up transform using SWC
- Auto mocking stylesheets (.css, .module.css, and their scss variants) and image imports
- Loading .env (and all variants) into process.env
- Ignoring node_modules from test resolving and transforms
- Ignoring .next from test resolving
- Loading next.config.js for flags that enable SWC transforms
// jest.config.js
const nextJest = require('next/jest')
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
/** @type {import('jest').Config} */
const customJestConfig = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
// __mocks__/fileMock.js
module.exports = {
src: '/img.jpg',
height: 24,
width: 24,
blurDataURL: 'data:image/png;base64,imagedata',
}
// __mocks__/styleMock.js
module.exports = {}
// package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest --watch"
}
// __tests__/index.test.tsx
// we can add a test to check if the <Home /> component successfully renders a heading:
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'
import '@testing-library/jest-dom'
describe('Home', () => {
it('renders a heading', () => {
render(<Home />)
const heading = screen.getByRole('heading', {
name: /welcome to next\.js!/i,
})
expect(heading).toBeInTheDocument()
})
})