Vite ํ๊ฒฝ์์์ ํ ์คํธ ํ๋ ์์ํฌ์ธ Vitest โ๏ธโ
yarn add -D vitest
{
"scripts": {
"test": "vitest"
}
}
vite.config.ts
๋ก ์ค์ vitest.config.ts
๋ก ์ค์ src/test
ํด๋ ์์ example.test.ts
ํ์์ผ๋ก ํ
์คํธ ํ์ผ ์์ฑ// sum.ts
export function sum(a: number, b: number): number {
return a + b;
}
// sum.test.ts
import { expect, test } from 'vitest';
import { sum } from '../sum';
test('๋ง์
ํ
์คํธ 1 + 2 = 3', () => {
expect(sum(1, 2)).toBe(3);
});
yarn test
yarn add jsdom
vite.config.ts
ํ์ผ ์ค์ import { InlineConfig, UserConfig, defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
interface VitestConfigExport extends UserConfig {
test: InlineConfig;
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
},
} as VitestConfigExport);
- React ํ
์คํ
๋ผ์ด๋ธ๋ฌ๋ฆฌ
yarn add @testing-library/react
- ํ
์คํธ ์คํ์ ์ํ DOM ํ๊ฒฝ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
yarn add @testing-library/jest-dom
- ์ ์ ๊ฐ ๋ฐ์์ํค๋ ์ด๋ฒคํธ ํ
์คํธ๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
yarn add @testing-library/user-event
/test/setup.ts
์ setup ํ์ผ ์์ฑ@testing-library/jest-dom
๋ Jest๋ฅผ ํตํด ํ
์คํ
์ ํ ๋ DOM์ ๋ํ ๋งค์ฒ(matcher)์ ์ ํธ๋ฆฌํฐ ํจ์ ์ ๊ณตํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ@testing-library/jest-dom/vitest
๋ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ vitest ๋ฒ์ jest-dom
์ ๋งค์ฒ๋ค๊ณผ ์ ํธ๋ฆฌํฐ ํจ์๋ฅผ ์ฌ์ฉ// setup.ts
import '@testing-library/jest-dom/vitest';
vite.config.ts
ํ์ผ ์ค์ ...
test: {
globals: true,
environment: 'jsdom',
setupFiles: './src/tests/setup.js',
},
...
type InputProps = {
label: string;
name: string;
} & React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>;
export function Input({ label, name, ...props }: InputProps) {
return (
<>
<label htmlFor={name}>{label}</label>
<input name={name} id={name} {...props} />
</>
);
}
import { describe, expect, it } from 'vitest';
import { Input } from '../components/Input';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('Input', async () => {
it('Input ์ปดํฌ๋ํธ ๋ ๋๋ง', () => {
// render() : <Input /> ๋ ๋๋ง
render(
<Input
name='email'
type='email'
placeholder='Email'
label='Email Address'
/>
);
// 'Email Address' ํ
์คํธ๋ฅผ ํฌํจํ ์์๊ฐ ํ๋ฉด์ ์กด์ฌํ๋์ง ๊ฒ์ฆ
expect(screen.getByText('Email Address')).toBeInTheDocument();
// 'email address'๋ผ๋ ๋ผ๋ฒจ์ ๊ฐ์ง ํ
์คํธ๋ฐ์ค(role์ด textbox์ธ ์์)๊ฐ ํ๋ฉด์ ์กด์ฌํ๋์ง๋ฅผ ๊ฒ์ฆ
// toBeInTheDocument() : ํน์ ์์๊ฐ ๋ฌธ์ ์์ ์กด์ฌํ๋์ง๋ฅผ ํ
์คํธ
expect(
screen.getByRole('textbox', {
name: /email address/i,
})
).toBeInTheDocument();
});
// ํน์ ์
๋ ฅ ์์์ ๊ฐ์ ๋ณ๊ฒฝํ๋์ง๋ฅผ ํ
์คํธ
it('Input ๊ฐ ๋ณ๊ฒฝ', async () => {
render(
<Input
name='email'
type='email'
placeholder='Email'
label='Email Address'
/>
);
const input = screen.getByRole('textbox', {
name: /email address/i,
});
// userEvent.type()์ ์ฌ์ฉํ์ฌ input ์์์ '1234' ๊ฐ ์
๋ ฅ
await userEvent.type(input, '1234');
// ํด๋น input ์์์ ๊ฐ์ด '1234'์ธ์ง ํ์ธ
expect(input).toHaveValue('1234');
});