๐Ÿšค ์„ฑ์žฅ์ผ์ง€ 7.0

์ฑ… ํ–‰๋ณตํ•œ ์ด๊ธฐ์ฃผ์˜์ž(์›จ์ธ ๋‹ค์ด์–ด)์˜ ๋‚ด์šฉ์— ์ž๊ทน๋ฐ›์•„ ์‹œ์ž‘ํ•˜๋Š” ์†Œ๋ฐ•ํ•œ ์„ฑ์žฅ๊ธฐ๋ก

์‚ด์•„์žˆ๋Š” ๊ฝƒ๊ณผ ์ฃฝ์€ ๊ฝƒ์€ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ณ„ํ•˜๋Š”๊ฐ€?
์„ฑ์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
์ƒ๋ช…์˜ ์œ ์ผํ•œ ์ฆ๊ฑฐ๋Š” ์„ฑ์žฅ์ด๋‹ค!

โš› (7.0)<์™„์ „ ๊ฐœํŽธ> ํŒŒ์ธ๋งŒ ํ•™์Šต๋ฒ•์„ ์•Œ๊ฒŒ ๋œ๋งŒํผ, ์„ฑ์žฅ์ผ์ง€๋Š” ์ •๋ง ๊ทธ ๋‚ ์˜ ํ‚ค์›Œ๋“œ ์ค‘์‹ฌ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.

โš›๏ธ ํ‚ค์›Œ๋“œ: ์ง๊ด€์ ์ด๊ณ  ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

  • ์†Œํ”„ํŠธ์›จ์–ด ํ…Œ์ŠคํŠธ๋Š” ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์˜๋„ํ•œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.(๊ฐœ๋ฐœ์ž๋Š” ํ•ญ์ƒ ๋ญ๋“ ์ง€ ์ž๋™ํ™”ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ด์•ผ ํ•œ๋‹ค!!! ํšจ์œจ์ ์œผ๋กœ ์‚ด์ž!!!)
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•จ์œผ๋กœ์จ ํ…Œ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ณ , ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
      1. ๋น ๋ฅธ ์ฃผ๊ธฐ๋กœ ๋‚ด ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
      1. ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฐœ๋ฐœ ์ค‘์— ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
      1. ์ฆ‰, ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•จ์— ์žˆ์–ด์„œ ๋” ํ™•์‹ ์„ ๊ฐ–๊ณ  ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋Œ€์ƒ์˜ ๊ทœ๋ชจ์— ๋”ฐ๋ผ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ, E2E ํ…Œ์ŠคํŠธ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
      1. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ: ํ•จ์ˆ˜, ๋ชจ๋“ˆ, ํด๋ž˜์Šค ๋“ฑ์˜ ๋‹จ์œ„๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ
      1. ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ: ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ
      1. E2E ํ…Œ์ŠคํŠธ: ์‚ฌ์šฉ์ž์˜ ๊ด€์ ์—์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ

์‚ฌ์‹ค์ƒ ํ”„๋ก ํŠธ์—”๋“œ ์ง„์˜์—์„œ๋Š” ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ›จ์”ฌ ๋งŽ์ด ์ ์šฉํ•˜๊ณ , ๋น„๊ต์  ๋น„์šฉ์ด ํฐ E2E ํ…Œ์ŠคํŠธ๋Š” ๊ทธ ๋นˆ๋„๊ฐ€ ๋” ์ ๋‹ค๊ณ  ํ•œ๋‹ค.

Jest(Javascript Test) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • JavaScript ์ง„์˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.(์ด์™ธ์—๋„ Mocha, Chai, Jasmine ๋“ฑ์ด ์žˆ๋‹ค.)
  • *.test.* ํ˜•ํƒœ์˜ ํŒŒ์ผ์„ ๋ชจ๋‘ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ์ธ์ง€ํ•œ๋‹ค.
  • ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ๋ˆ๋‹ค.
test('ํ…Œ์ŠคํŠธ ์„ค๋ช…', () => {
  // ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์…‹์—…(๋ณ€์ˆ˜ ์„ ์–ธ, ํ•จ์ˆ˜ ์„ ์–ธ ๋“ฑ)
  expect('ํ…Œ์ŠคํŠธ ๋Œ€์ƒ').toBe('๊ธฐ๋Œ€ ๊ฒฐ๊ณผ');
});
  • ์ด ๋•Œ, toBe()์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ matcher๋ผ๊ณ  ํ•œ๋‹ค.

React Testing Library(RTL)

  • React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.
  • RTL์€ ์ฝ”๋“œ์˜ ๊ตฌ์ฒด์ ์ธ ๊ณผ์ •์ด ์•„๋‹ˆ๋ผ ๊ฒฐ๊ณผ ์ฆ‰, ํ™”๋ฉด์— ๋ฌด์—‡์ด ๋ Œ๋”๋ง๋˜๋Š”์ง€์— ์ดˆ์ ์„ ๋งž์ถ˜๋‹ค.
    • ์ฐธ๊ณ ) Enzyme์€ ์ฝ”๋“œ์˜ ๊ตฌ์ฒด์ ์ธ ๊ณผ์ •์— ์ดˆ์ ์„ ๋งž์ถ˜๋‹ค.
    • ์˜ˆ์‹œ) ์–ด๋–ค state๋ฅผ useState๋กœ ๊ด€๋ฆฌํ•˜๋‹ค๊ฐ€ Recoil๋กœ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ์„ ๋•Œ, Enzyme์€ ์ฝ”๋“œ์˜ ๊ตฌ์ฒด์ ์ธ ๊ณผ์ •์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค. ๋ฐ˜๋ฉด์— RTL์€ ํ™”๋ฉด์— ๋ฌด์—‡์ด ๋ Œ๋”๋ง๋˜๋Š”์ง€์— ์ดˆ์ ์„ ๋งž์ถ”๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ๋ˆ๋‹ค.
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import App from './App';

test('App rendering', () => {
  render(<App />);

  const header = screen.getByText('Hello World');
  const button = screen.getByText('Click me!');

  userEvent.click(button);
  // import '@testing-library/jest-dom'๋ฅผ ํ†ตํ•ด์„œ dom๊ณผ ๊ด€๋ จ๋œ matcher ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  expect(header).toBeInTheDocument();
  expect(button).toBeDisabled();
});

TDD(Test Driven Development)

  • ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ๋กœ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ž‘์„ฑํ•˜๊ณ  ๊ทธ์— ๋งž์ถฐ์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
  • 3๊ฐ€์ง€ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์„œ ์ง„ํ–‰๋œ๋‹ค.
      1. Red: ๋ฌด์กฐ๊ฑด ์‹คํŒจํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ(๋‹น์—ฐํžˆ ํ•จ์ˆ˜๊ฐ€ ์—†๋Š”๋ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋งŒ ์žˆ์œผ๋‹ˆ๊นŒ!)
      1. Green: ๋ฌด์‹ํ•˜๊ฒŒ๋ผ๋„ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š” ์ฝ”๋“œ ์ž‘์„ฑ
      1. Blue: Green ๋‹จ๊ณ„์˜ ์ฝ”๋“œ๋ฅผ ๋” ์ข‹์€ ํ˜•ํƒœ๋กœ ๋ฆฌํŒฉํ† ๋ง

๐Ÿ“ ํšŒ๊ณ 

์˜ค๋Š˜์€ ํ•˜๋ฃจ์ข…์ผ Recharts์˜ ๊ณต์‹๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด์„œ ์ฐจํŠธ์— ์žˆ์–ด์„œ์˜ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ๊ณผ props๋“ค์„ ์‚ดํŽด๋ณด๊ณ  ์ ์šฉํ–ˆ๋‹ค. ์š”๊ตฌ์‚ฌํ•ญ์— ํ•ด๋‹นํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋ชจ๋‘ ๊ตฌํ˜„์ด ๋๋‚˜์„œ, ์˜ค๋Š˜ ์„ธ์…˜ ๋•Œ ๋“ค์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์—ด์‹ฌํžˆ ์ ์šฉํ–ˆ๋Š”๋ฐ, ์ด๋†ˆ์˜ styled-components๋•Œ๋ฌธ์— ์•ฝ๊ฐ„์˜ ์—๋Ÿฌ๋“ค์ด ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๊ฒฐ๊ตญ์—” ThemeProvider๋ฅผ ๊ฐ์‹ธ์ฃผ๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋‹ˆ ๊ดœ์ฐฎ์•˜๋‹ค. ๋‚ด์ผ์€ ๋‚˜์•„๊ฐ€์„œ styled-components์˜ style์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ์‹œ๊ฐ„์ด ๋œ๋‹ค๋ฉด cypress๋ฅผ ํ†ตํ•ด์„œ E2E ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๋ ค ํ•œ๋‹ค.

์ฐธ๊ณ