๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค ๊ตฌ์ถ์ ์ํ ์ค์ฉ์ ์ธ ์์ ์ ํจ๊ป ์ค๋ ์ท ๋ฐ ํตํฉ ํ ์คํธ ์ ๋ต์ ๋ค๋ฃจ๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ํ ์คํ ์ข ํฉ ๊ฐ์ด๋์ ๋๋ค.
๋ฆฌ์กํธ ์ปดํฌ๋ํธ ํ ์คํ : ์ค๋ ์ท ๋ฐ ํตํฉ ํ ์คํธ ๋ง์คํฐํ๊ธฐ
ํ๋ ์น ๊ฐ๋ฐ์ ์ธ๊ณ์์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค(UI)์ ์ ๋ขฐ์ฑ๊ณผ ๊ฒฌ๊ณ ์ฑ์ ๋ณด์ฅํ๋ ๊ฒ์ ๋ฌด์๋ณด๋ค ์ค์ํฉ๋๋ค. UI ๊ตฌ์ถ์ ์ํ ์ธ๊ธฐ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ ๋ฆฌ์กํธ๋ ๊ฐ๋ฐ์์๊ฒ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ์ปดํฌ๋ํธ๋ฅผ ์ฒ ์ ํ ํ ์คํธํ๋ ๊ฒ์ ๊ณ ํ์ง์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด ๊ธ์์๋ ๋ ๊ฐ์ง ํ์์ ์ธ ํ ์คํธ ์ ๋ต์ธ ์ค๋ ์ท ํ ์คํ ๊ณผ ํตํฉ ํ ์คํ ์ ๋ํด ์์ธํ ์์๋ณด๊ณ , ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ํ ์คํ ์ ๋ง์คํฐํ๋ ๋ฐ ๋์์ด ๋๋ ์ค์ฉ์ ์ธ ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํด์ผ ํ ๊น์?
์ค๋ ์ท ๋ฐ ํตํฉ ํ ์คํธ์ ์ธ๋ถ ์ฌํญ์ ๋ํด ์์๋ณด๊ธฐ ์ ์, ๋จผ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํ๋ ๊ฒ์ด ์ ์ค์ํ์ง ์ดํดํด ๋ด ์๋ค:
- ํ๊ท(Regression) ๋ฐฉ์ง: ํ ์คํธ๋ ์ปดํฌ๋ํธ ๋์์ ์๊ธฐ์น ์์ ๋ณ๊ฒฝ์ ๊ฐ์งํ์ฌ ์ฝ๋๋ฒ ์ด์ค์ ํ๊ท๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ์ฝ๋ ํ์ง ํฅ์: ํ ์คํธ๋ฅผ ์์ฑํ๋ฉด ์ปดํฌ๋ํธ์ ๋์์ธ๊ณผ ๊ตฌ์กฐ์ ๋ํด ๋ ๊น์ด ์๊ฐํ๊ฒ ๋์ด ๋ ๊นจ๋ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ข์ ์ฝ๋๋ก ์ด์ด์ง๋๋ค.
- ์์ ๊ฐ ํฅ์: ํฌ๊ด์ ์ธ ํ ์คํธ ์ค์ํธ๊ฐ ์์ผ๋ฉด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ๋ ๋ฌด์ธ๊ฐ ์๋ชป๋ ๊ฒฝ์ฐ ์๋ฆผ์ ๋ฐ์ ์ ์๋ค๋ ์ฌ์ค์ ์๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค.
- ํ์ ์ด์ง: ํ ์คํธ๋ ์ปดํฌ๋ํธ์ ๋ํ ๋ฌธ์ ์ญํ ์ ํ์ฌ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ๊ณ ์์ ํ ์ ์๋๋ก ๋์ต๋๋ค.
์ค๋ ์ท ํ ์คํ
์ค๋ ์ท ํ ์คํ ์ด๋?
์ค๋ ์ท ํ ์คํ ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฌผ(์ค๋ ์ท)์ ์ด์ ์ ์ ์ฅ๋ ์ค๋ ์ท๊ณผ ๋น๊ตํ๋ ๋ฐฉ์์ ๋๋ค. ๋ง์ฝ ์ฐจ์ด์ ์ด ์๋ค๋ฉด ํ ์คํธ๋ ์คํจํ๋ฉฐ, ์ด๋ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ๋ํ๋ ๋๋ค. ์ด๋ ์ปดํฌ๋ํธ์ ์ถ๋ ฅ๋ฌผ์ ๋ํ "์ฌ์ง"์ ์ฐ๊ณ ๊ทธ๊ฒ์ด ์๊ธฐ์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์์๋์ง ํ์ธํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
์ค๋ ์ท ํ ์คํ ์ UI๊ฐ ์๋์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์์๋์ง ํ์ธํ๋ ๋ฐ ํนํ ์ ์ฉํฉ๋๋ค. ์ฃผ๋ก ์คํ์ผ๋ง, ๋ ์ด์์ ๋๋ ์ปดํฌ๋ํธ์ ์ ๋ฐ์ ์ธ ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ๊ฐ์งํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์ค๋ ์ท ํ ์คํ ๊ตฌํ ๋ฐฉ๋ฒ
์ค๋ ์ท ํ ์คํ ์ ์์ฐํ๊ธฐ ์ํด ์ธ๊ธฐ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํ ํ๋ ์์ํฌ์ธ Jest์ Enzyme (๋๋ React Testing Library - ์๋ ์ฐธ์กฐ)์ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
Jest์ Enzyme์ ์ฌ์ฉํ ์์ (์ฌ์ฉ ์ค๋จ ์๋ฆผ):
์ฐธ๊ณ : Enzyme์ React Testing Library๋ฅผ ์ ํธํ๋ ๋ง์ ์ฌ๋๋ค์ ์ํด ์ฌ์ฉ์ด ์ค๋จ๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค. ์ด ์์ ๋ Enzyme ์ฌ์ฉ๋ฒ์ ๋ณด์ฌ์ฃผ์ง๋ง, ์๋ก์ด ํ๋ก์ ํธ์๋ React Testing Library๋ฅผ ๊ถ์ฅํฉ๋๋ค.
๋จผ์ Jest์ Enzyme์ ์ค์นํฉ๋๋ค:
npm install --save-dev jest enzyme enzyme-adapter-react-16
npm install --save react-test-renderer
์ฌ์ฉํ๋ ๋ฆฌ์กํธ ๋ฒ์ ์ ๋ง๋ ์ด๋ํฐ๋ก `react-adapter-react-16`์ ๊ต์ฒดํ์ธ์.
๊ฐ๋จํ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ญ๋๋ค (์: Greeting.js):
import React from 'react';
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
export default Greeting;
์ด์ ์ค๋
์ท ํ
์คํธ๋ฅผ ๋ง๋ญ๋๋ค (์: Greeting.test.js):
import React from 'react';
import { shallow } from 'enzyme';
import Greeting from './Greeting';
descibe('Greeting Component', () => {
it('renders correctly', () => {
const wrapper = shallow(<Greeting name="World" />);
expect(wrapper).toMatchSnapshot();
});
});
Jest๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ๋ฅผ ์คํํฉ๋๋ค:
npm test
ํ
์คํธ๋ฅผ ์ฒ์ ์คํํ๋ฉด Jest๋ Greeting ์ปดํฌ๋ํธ์ ๋ ๋๋ง๋ ์ถ๋ ฅ์ ํฌํจํ๋ ์ค๋
์ท ํ์ผ(์: __snapshots__/Greeting.test.js.snap)์ ์์ฑํฉ๋๋ค.
์ดํ์ ํ ์คํธ ์คํ์ ํ์ฌ ์ถ๋ ฅ์ ์ ์ฅ๋ ์ค๋ ์ท๊ณผ ๋น๊ตํฉ๋๋ค. ์ผ์นํ๋ฉด ํ ์คํธ๋ ํต๊ณผํฉ๋๋ค. ๋ค๋ฅด๋ฉด ํ ์คํธ๋ ์คํจํ๋ฉฐ, ๋ณ๊ฒฝ ์ฌํญ์ ๊ฒํ ํ๊ณ ์ค๋ ์ท์ ์ ๋ฐ์ดํธํ๊ฑฐ๋ ์ปดํฌ๋ํธ๋ฅผ ์์ ํด์ผ ํฉ๋๋ค.
Jest์ React Testing Library๋ฅผ ์ฌ์ฉํ ์์ :
React Testing Library๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํ๋ ๋ฐ ์์ด ๋ ํ๋์ ์ด๊ณ ๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ด๋ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ์ง์คํ๊ธฐ๋ณด๋ค๋ ์ฌ์ฉ์ ๊ด์ ์์ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค.
๋จผ์ Jest์ React Testing Library๋ฅผ ์ค์นํฉ๋๋ค:
npm install --save-dev @testing-library/react @testing-library/jest-dom jest
์ค๋
์ท ํ
์คํธ๋ฅผ ์์ ํฉ๋๋ค (์: Greeting.test.js):
import React from 'react';
import { render } from '@testing-library/react';
import Greeting from './Greeting';
import '@testing-library/jest-dom/extend-expect';
descibe('Greeting Component', () => {
it('renders correctly', () => {
const { asFragment } = render(<Greeting name="World" />);
expect(asFragment()).toMatchSnapshot();
});
});
Jest๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ๋ฅผ ์คํํฉ๋๋ค:
npm test
ํ
์คํธ๋ฅผ ์ฒ์ ์คํํ๋ฉด Jest๋ Greeting ์ปดํฌ๋ํธ์ ๋ ๋๋ง๋ ์ถ๋ ฅ์ ํฌํจํ๋ ์ค๋
์ท ํ์ผ(์: __snapshots__/Greeting.test.js.snap)์ ์์ฑํฉ๋๋ค.
์ดํ์ ํ ์คํธ ์คํ์ ํ์ฌ ์ถ๋ ฅ์ ์ ์ฅ๋ ์ค๋ ์ท๊ณผ ๋น๊ตํฉ๋๋ค. ์ผ์นํ๋ฉด ํ ์คํธ๋ ํต๊ณผํฉ๋๋ค. ๋ค๋ฅด๋ฉด ํ ์คํธ๋ ์คํจํ๋ฉฐ, ๋ณ๊ฒฝ ์ฌํญ์ ๊ฒํ ํ๊ณ ์ค๋ ์ท์ ์ ๋ฐ์ดํธํ๊ฑฐ๋ ์ปดํฌ๋ํธ๋ฅผ ์์ ํด์ผ ํฉ๋๋ค.
์ค๋ ์ท ํ ์คํ ๋ชจ๋ฒ ์ฌ๋ก
- ์ค๋ ์ท์ ์ฝ๋๋ก ์ทจ๊ธํ๊ธฐ: ์ค๋ ์ท ํ์ผ์ ๋ค๋ฅธ ์ฝ๋ ํ์ผ์ฒ๋ผ ๋ฒ์ ๊ด๋ฆฌ ์์คํ (์: Git)์ ์ปค๋ฐํ์ธ์.
- ๋ณ๊ฒฝ ์ฌํญ ์ ์คํ๊ฒ ๊ฒํ ํ๊ธฐ: ์ค๋ ์ท ํ ์คํธ๊ฐ ์คํจํ๋ฉด, ์ค๋ ์ท ํ์ผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ ์ธ ๊ฒ์ธ์ง ๋ฒ๊ทธ๋ฅผ ๋ํ๋ด๋์ง ์ ์คํ๊ฒ ๊ฒํ ํ์ธ์.
- ์๋์ ์ผ๋ก ์ค๋ ์ท ์ ๋ฐ์ดํธํ๊ธฐ: ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ ์ธ ๊ฒฝ์ฐ, ์๋ก์ด ์์ ์ถ๋ ฅ์ ๋ฐ์ํ๋๋ก ์ค๋ ์ท ํ์ผ์ ์ ๋ฐ์ดํธํ์ธ์.
- ์ค๋ ์ท ๋จ์ฉํ์ง ์๊ธฐ: ์ค๋ ์ท ํ ์คํ ์ UI๊ฐ ๋น๊ต์ ์์ ์ ์ธ ์ปดํฌ๋ํธ์ ๊ฐ์ฅ ์ ํฉํฉ๋๋ค. ์์ฃผ ๋ณ๊ฒฝ๋๋ ์ปดํฌ๋ํธ์ ์ฌ์ฉํ๋ฉด ๋ถํ์ํ ์ค๋ ์ท ์ ๋ฐ์ดํธ๊ฐ ๋ง์ด ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ํผํ์ธ์.
- ๊ฐ๋ ์ฑ ๊ณ ๋ คํ๊ธฐ: ๋๋ก๋ ์ค๋ ์ท ํ์ผ์ ์ฝ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค. Prettier์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ ์ท ํ์ผ์ ํ์์ ์ง์ ํ์ฌ ๊ฐ๋ ์ฑ์ ๋์ด์ธ์.
์ธ์ ์ค๋ ์ท ํ ์คํ ์ ์ฌ์ฉํด์ผ ํ ๊น์?
์ค๋ ์ท ํ ์คํ ์ ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค์์ ๊ฐ์ฅ ํจ๊ณผ์ ์ ๋๋ค:
- ๋จ์ํ ์ปดํฌ๋ํธ: ์์ธก ๊ฐ๋ฅํ ์ถ๋ ฅ์ ๊ฐ์ง ๊ฐ๋จํ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํ ๋.
- UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ์ฌ๋ฌ ๋ฒ์ ์ ๊ฑธ์ณ UI ์ปดํฌ๋ํธ์ ์๊ฐ์ ์ผ๊ด์ฑ์ ํ์ธํ ๋.
- ํ๊ท ํ ์คํธ: ๊ธฐ์กด ์ปดํฌ๋ํธ์ ์๋์น ์์ ๋ณ๊ฒฝ์ ๊ฐ์งํ ๋.
ํตํฉ ํ ์คํ
ํตํฉ ํ ์คํ ์ด๋?
ํตํฉ ํ ์คํ ์ ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ํจ๊ป ์๋ํ์ฌ ํน์ ๊ธฐ๋ฅ์ ๋ฌ์ฑํ๋ ๋ฐฉ์์ ํ ์คํธํ๋ ๊ฒ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ํธ ์์ฉํ๊ณ ์ ์ฒด ์์คํ ์ด ์์๋๋ก ๋์ํ๋์ง ํ์ธํฉ๋๋ค.
๊ฐ๋ณ ์ปดํฌ๋ํธ์ ์ด์ ์ ๋ง์ถ๋ ๋จ์ ํ ์คํธ์ ๋ฌ๋ฆฌ, ํตํฉ ํ ์คํธ๋ ์ปดํฌ๋ํธ ๊ฐ์ ์ํธ ์์ฉ์ ์ค์ ์ ๋ก๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ์ฒด์ ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
ํตํฉ ํ ์คํ ๊ตฌํ ๋ฐฉ๋ฒ
์ฌ๊ธฐ์๋ Jest์ React Testing Library๋ฅผ ์ฌ์ฉํ์ฌ ํตํฉ ํ ์คํ ์ ์์ฐํด ๋ณด๊ฒ ์ต๋๋ค.
Input๊ณผ Display๋ผ๋ ๋ ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ง ๊ฐ๋จํ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. Input ์ปดํฌ๋ํธ๋ ์ฌ์ฉ์๊ฐ ํ
์คํธ๋ฅผ ์
๋ ฅํ ์ ์๊ฒ ํ๊ณ , Display ์ปดํฌ๋ํธ๋ ์
๋ ฅ๋ ํ
์คํธ๋ฅผ ํ์ํฉ๋๋ค.
๋จผ์ , Input ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ญ๋๋ค (์: Input.js):
import React, { useState } from 'react';
function Input({ onInputChange }) {
const [text, setText] = useState('');
const handleChange = (event) => {
setText(event.target.value);
onInputChange(event.target.value);
};
return (
<input
type="text"
value={text}
onChange={handleChange}
placeholder="Enter text..."
/>
);
}
export default Input;
๋ค์์ผ๋ก, Display ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ญ๋๋ค (์: Display.js):
import React from 'react';
function Display({ text }) {
return <p>You entered: {text}</p>;
}
export default Display;
์ด์ Input๊ณผ Display ์ปดํฌ๋ํธ๋ฅผ ํตํฉํ๋ ๋ฉ์ธ App ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ญ๋๋ค (์: App.js):
import React, { useState } from 'react';
import Input from './Input';
import Display from './Display';
function App() {
const [inputText, setInputText] = useState('');
const handleInputChange = (text) => {
setInputText(text);
};
return (
<div>
<Input onInputChange={handleInputChange} />
<Display text={inputText} />
</div>
);
}
export default App;
ํตํฉ ํ
์คํธ๋ฅผ ๋ง๋ญ๋๋ค (์: App.test.js):
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import App from './App';
import '@testing-library/jest-dom/extend-expect';
describe('App Component', () => {
it('updates the display when the input changes', () => {
render(<App />);
const inputElement = screen.getByPlaceholderText('Enter text...');
const displayElement = screen.getByText('You entered: ');
fireEvent.change(inputElement, { target: { value: 'Hello, world!' } });
expect(displayElement).toHaveTextContent('You entered: Hello, world!');
});
});
Jest๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ๋ฅผ ์คํํฉ๋๋ค:
npm test
์ด ํ
์คํธ๋ ์ฌ์ฉ์๊ฐ Input ์ปดํฌ๋ํธ์ ํ
์คํธ๋ฅผ ์
๋ ฅํ๋ ๊ฒ์ ์๋ฎฌ๋ ์ด์
ํ๊ณ Display ์ปดํฌ๋ํธ๊ฐ ์
๋ ฅ๋ ํ
์คํธ๋ก ์
๋ฐ์ดํธ๋๋์ง ํ์ธํฉ๋๋ค. ์ด๋ Input๊ณผ Display ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ํธ ์์ฉํ๊ณ ์์์ ํ์ธํฉ๋๋ค.
ํตํฉ ํ ์คํ ๋ชจ๋ฒ ์ฌ๋ก
- ํต์ฌ ์ํธ ์์ฉ์ ์ง์คํ๊ธฐ: ์ปดํฌ๋ํธ ๊ฐ์ ๊ฐ์ฅ ์ค์ํ ์ํธ ์์ฉ์ ์๋ณํ๊ณ ํตํฉ ํ ์คํธ๋ฅผ ๊ฑฐ๊ธฐ์ ์ง์คํ์ธ์.
- ํ์ค์ ์ธ ๋ฐ์ดํฐ ์ฌ์ฉํ๊ธฐ: ํตํฉ ํ ์คํธ์์ ์ค์ ์ ์ ์ฌํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ค์ ์ธ ์๋๋ฆฌ์ค๋ฅผ ์๋ฎฌ๋ ์ด์ ํ์ธ์.
- ์ธ๋ถ ์์กด์ฑ ๋ชจ์(Mock) ์ฒ๋ฆฌํ๊ธฐ: API ํธ์ถ๊ณผ ๊ฐ์ ์ธ๋ถ ์์กด์ฑ์ ๋ชจ์ ์ฒ๋ฆฌํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ๊ณ ํ ์คํธ์ ์ ๋ขฐ์ฑ์ ๋์ด์ธ์. `msw`(Mock Service Worker)์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด ์์ ์ ํ์ํฉ๋๋ค.
- ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ํ ์คํธ ์์ฑํ๊ธฐ: ์ดํดํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ํ ์คํธ๋ฅผ ์์ฑํ์ธ์.
- ์ฌ์ฉ์ ํ๋ฆ ํ ์คํธํ๊ธฐ: ์์ ํ ์ฌ์ฉ์ ํ๋ฆ์ ํ ์คํธํ๋ ๋ฐ ์ง์คํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฌ์ฉ์ ๊ด์ ์์ ์์๋๋ก ๋์ํ๋์ง ํ์ธํ์ธ์.
์ธ์ ํตํฉ ํ ์คํ ์ ์ฌ์ฉํด์ผ ํ ๊น์?
ํตํฉ ํ ์คํ ์ ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค์์ ๊ฐ์ฅ ํจ๊ณผ์ ์ ๋๋ค:
- ๋ณต์กํ ์ปดํฌ๋ํธ: ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ ์ธ๋ถ ์์คํ ๊ณผ ์ํธ ์์ฉํ๋ ๋ณต์กํ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํ ๋.
- ์ฌ์ฉ์ ํ๋ฆ: ์์ ํ ์ฌ์ฉ์ ํ๋ฆ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ ๋.
- API ์ํธ ์์ฉ: ํ๋ก ํธ์๋์ ๋ฐฑ์๋ API ๊ฐ์ ํตํฉ์ ํ ์คํธํ ๋.
์ค๋ ์ท ํ ์คํ vs. ํตํฉ ํ ์คํ : ๋น๊ต
๋ค์์ ์ค๋ ์ท ํ ์คํ ๊ณผ ํตํฉ ํ ์คํ ์ ์ฃผ์ ์ฐจ์ด์ ์ ์์ฝํ ํ์ ๋๋ค:
| ๊ธฐ๋ฅ | ์ค๋ ์ท ํ ์คํ | ํตํฉ ํ ์คํ |
|---|---|---|
| ๋ชฉ์ | UI ๊ฒฐ๊ณผ๋ฌผ์ด ์๊ธฐ์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์์๋์ง ํ์ธ. | ์ปดํฌ๋ํธ๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ํธ ์์ฉํ๋์ง ํ์ธ. |
| ๋ฒ์ | ๊ฐ๋ณ ์ปดํฌ๋ํธ ๋ ๋๋ง. | ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ํ๋ ฅ. |
| ์ด์ | UI ์ธํ. | ์ปดํฌ๋ํธ ์ํธ ์์ฉ ๋ฐ ๊ธฐ๋ฅ. |
| ๊ตฌํ | ๋ ๋๋ง๋ ๊ฒฐ๊ณผ๋ฌผ์ ์ ์ฅ๋ ์ค๋ ์ท๊ณผ ๋น๊ต. | ์ฌ์ฉ์ ์ํธ ์์ฉ์ ์๋ฎฌ๋ ์ด์ ํ๊ณ ์์ ๋์์ ํ์ธ. |
| ์ฌ์ฉ ์ฌ๋ก | ๋จ์ ์ปดํฌ๋ํธ, UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํ๊ท ํ ์คํธ. | ๋ณต์กํ ์ปดํฌ๋ํธ, ์ฌ์ฉ์ ํ๋ฆ, API ์ํธ ์์ฉ. |
| ์ ์ง๋ณด์ | ์๋์ ์ธ UI ๋ณ๊ฒฝ ์ ์ค๋ ์ท ์ ๋ฐ์ดํธ ํ์. | ์ปดํฌ๋ํธ ์ํธ ์์ฉ์ด๋ ๊ธฐ๋ฅ ๋ณ๊ฒฝ ์ ์ ๋ฐ์ดํธ ํ์. |
์ฌ๋ฐ๋ฅธ ํ ์คํธ ์ ๋ต ์ ํํ๊ธฐ
์ต๊ณ ์ ํ ์คํธ ์ ๋ต์ ํ๋ก์ ํธ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก, ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ค๋ ์ท ํ ์คํ ๊ณผ ํตํฉ ํ ์คํ ์ ์กฐํฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
- ๋จ์ ํ ์คํธ๋ก ์์ํ๊ธฐ: ์ค๋ ์ท์ด๋ ํตํฉ ํ ์คํธ๋ฅผ ์์ํ๊ธฐ ์ ์, ๊ฐ๋ณ ์ปดํฌ๋ํธ์ ๋ํ ์ข์ ๋จ์ ํ ์คํธ๊ฐ ์๋์ง ํ์ธํ์ธ์.
- UI ์ปดํฌ๋ํธ์ ์ค๋ ์ท ํ ์คํธ ์ฌ์ฉํ๊ธฐ: UI ์ปดํฌ๋ํธ์ ์๊ฐ์ ์ผ๊ด์ฑ์ ํ์ธํ๊ธฐ ์ํด ์ค๋ ์ท ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ธ์.
- ๋ณต์กํ ์ํธ ์์ฉ์ ํตํฉ ํ ์คํธ ์ฌ์ฉํ๊ธฐ: ์ปดํฌ๋ํธ๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ํธ ์์ฉํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์๋๋ก ๋์ํ๋์ง ํ์ธํ๊ธฐ ์ํด ํตํฉ ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ธ์.
- ์ข ๋จ ๊ฐ(E2E) ํ ์คํธ ๊ณ ๋ คํ๊ธฐ: ์ค์ํ ์ฌ์ฉ์ ํ๋ฆ์ ๋ํด์๋ Cypress๋ Playwright์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ์๋ฎฌ๋ ์ด์ ํ๊ณ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ๋์์ ํ์ธํ๋ ์ข ๋จ ๊ฐ ํ ์คํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
์ค๋ ์ท๊ณผ ํตํฉ ํ ์คํธ๋ฅผ ๋์ด์
์ค๋ ์ท๊ณผ ํตํฉ ํ ์คํธ๋ ์ค์ํ์ง๋ง, ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๋ํด ๊ณ ๋ คํด์ผ ํ ์ ์ผํ ํ ์คํธ ์ ํ์ ์๋๋๋ค. ๋ค์์ ์ผ๋์ ๋์ด์ผ ํ ๋ค๋ฅธ ํ ์คํธ ์ ๋ต๋ค์ ๋๋ค:
- ๋จ์ ํ ์คํธ: ์์ ์ธ๊ธํ๋ฏ์ด, ๋จ์ ํ ์คํธ๋ ๊ฐ๋ณ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ํ ์คํธํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
- ์ข ๋จ ๊ฐ(E2E) ํ ์คํธ: E2E ํ ์คํธ๋ ์ค์ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ์๋ฎฌ๋ ์ด์ ํ๊ณ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ๋์์ ํ์ธํฉ๋๋ค.
- ์์ฑ ๊ธฐ๋ฐ ํ ์คํธ: ์์ฑ ๊ธฐ๋ฐ ํ ์คํธ๋ ์ปดํฌ๋ํธ์ ๋ํด ํญ์ ์ฐธ์ด์ด์ผ ํ๋ ์์ฑ์ ์ ์ํ ๋ค์, ํด๋น ์์ฑ์ ํ ์คํธํ๊ธฐ ์ํด ๋ฌด์์ ์ ๋ ฅ์ ์์ฑํ๋ ๋ฐฉ์์ ๋๋ค.
- ์ ๊ทผ์ฑ ํ ์คํธ: ์ ๊ทผ์ฑ ํ ์คํธ๋ ์ปดํฌ๋ํธ๊ฐ ์ฅ์ ๋ฅผ ๊ฐ์ง ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํ์ง ํ์ธํฉ๋๋ค.
๊ฒฐ๋ก
ํ ์คํ ์ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ ๋ฆฌ์กํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ํ์์ ์ธ ๋ถ๋ถ์ ๋๋ค. ์ค๋ ์ท ๋ฐ ํตํฉ ํ ์คํ ๊ธฐ์ ์ ๋ง์คํฐํจ์ผ๋ก์จ ์ฝ๋์ ํ์ง์ ํฌ๊ฒ ํฅ์์ํค๊ณ , ํ๊ท๋ฅผ ๋ฐฉ์งํ๋ฉฐ, ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ๋ ๋ฐ ์์ ๊ฐ์ ๋์ผ ์ ์์ต๋๋ค. ๊ฐ ์ปดํฌ๋ํธ์ ๋ง๋ ์ฌ๋ฐ๋ฅธ ํ ์คํธ ์ ๋ต์ ์ ํํ๊ณ , ํฌ๊ด์ ์ธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ๋ค์ํ ์ ํ์ ํ ์คํธ๋ฅผ ์กฐํฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์. Jest, React Testing Library, ๊ทธ๋ฆฌ๊ณ Mock Service Worker (MSW)์ ๊ฐ์ ๋๊ตฌ๋ฅผ ํตํฉํ๋ฉด ํ ์คํธ ์ํฌํ๋ก์ฐ๋ฅผ ๊ฐ์ํํ ์ ์์ต๋๋ค. ํญ์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ฐ์ํ๋ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ฐ์ ์ํ์ธ์. ํ ์คํธ ๋ฌธํ๋ฅผ ์์ฉํจ์ผ๋ก์จ ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ํ๋ฅญํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๊ณ ํ์ง ๋ฆฌ์กํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.