chan9yu λ‹˜μ˜ μƒμ„ΈνŽ˜μ΄μ§€ > [5νŒ€ μ—¬μ°¬κ·œ] Chapter 🧦 3-1. ν”„λ‘ νŠΈμ—”λ“œ ν…ŒμŠ€νŠΈ μ½”λ“œ 🧦

Medium

7주차 과제 체크포인트

기본과제

Medium

  • 총 11개의 파일, 115개의 λ‹¨μœ„ ν…ŒμŠ€νŠΈλ₯Ό λ¬΄μ‚¬νžˆ μž‘μ„±ν•˜κ³  ν†΅κ³Όμ‹œν‚¨λ‹€.

질문

Q. medium.useEventOperations.spec.tsx > μ•„λž˜ toastFnκ³Ό mockκ³Ό 이 fn은 무엇을 ν•΄μ€„κΉŒμš”?

notistack 라이브러리의 useSnackbar 훅을 λͺ¨ν‚Ήν•˜μ—¬ ν…ŒμŠ€νŠΈ ν™˜κ²½μ—μ„œ μŠ€λ‚΅λ°” 호좜 여뢀와 λ©”μ‹œμ§€λ₯Ό 검증할 수 있게 ν•΄μ€λ‹ˆλ‹€. ν…ŒμŠ€νŠΈ ν™˜κ²½μ—μ„œλŠ” μ‹€μ œ UI μŠ€λ‚΅λ°”λ₯Ό λ„μš°μ§€ λͺ»ν•˜κΈ° λ•Œλ¬Έμ— enqueueSnackbarFn이 ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€, μ–΄λ–€ λ©”μ‹œμ§€κ°€ μ „λ‹¬λ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜λŠ” 방법을 μ‚¬μš©ν•©λ‹ˆλ‹€.

const enqueueSnackbarFn = vi.fn();

vi.mock('notistack', async () => {
  const actual = await vi.importActual('notistack');

  return {
    ...actual,
    useSnackbar: () => ({ enqueueSnackbar: enqueueSnackbarFn }),
  };
});

Q. medium.integration.spec.tsx > μ—¬κΈ°μ„œ ChakraProvider둜 λ¬Άμ–΄μ£ΌλŠ” λ™μž‘μ€ μ˜λ―Έμžˆμ„κΉŒμš”? μžˆλ‹€λ©΄ μ–΄λ–€ μ˜λ―ΈμΌκΉŒμš”?

ν…ŒμŠ€νŠΈ ν™˜κ²½μ—μ„œ μ‹€μ œ 운영 ν™˜κ²½κ³Ό λ™μΌν•œ Context μ œκ³΅μžλ“€μ„ μ„€μ •ν•˜μ—¬ μ»΄ν¬λ„ŒνŠΈκ°€ μ •μƒμ μœΌλ‘œ λ™μž‘ν•  수 있게 λ§Œλ“­λ‹ˆλ‹€. SnackbarProviderλŠ” notistackμ—μ„œ useSnackbar 훅을 μ‚¬μš©ν•  수 있게 λ§Œλ“œλŠ” μ»¨ν…μŠ€νŠΈ ν”„λ‘œλ°”μ΄λ”μ΄κ³ , ThemeProviderλŠ” MUI μ»΄ν¬λ„ŒνŠΈλ“€μ΄ themeλ₯Ό λ°›μ•„μ„œ μ˜¬λ°”λ₯΄κ²Œ λ Œλ”λ  수 있게 λ§Œλ“œλŠ” ν”„λ‘œλ°”μ΄λ”μž…λ‹ˆλ‹€.

import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { render } from '@testing-library/react';
import { SnackbarProvider } from 'notistack';
import type { ReactElement } from 'react';

import { App } from '../App';

//...

const setup = (element: ReactElement) => {
  const theme = createTheme();
  const user = userEvent.setup();

  return {
    ...render(
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <SnackbarProvider>{element}</SnackbarProvider>
      </ThemeProvider>
    ),
    user,
  };
};

Q. handlersUtils > μ•„λž˜ μ—¬λŸ¬κ°€μ§€ use ν•¨μˆ˜λŠ” μ–΄λ–€ 역할을 ν• κΉŒμš”? μ–΄λ–»κ²Œ μ‚¬μš©λ  수 μžˆμ„κΉŒμš”?

MSW의 server.use()λ₯Ό 톡해 νŠΉμ • ν…ŒμŠ€νŠΈμ—μ„œλ§Œ μ‚¬μš©ν•  μž„μ‹œ ν•Έλ“€λŸ¬λ₯Ό λ“±λ‘ν•©λ‹ˆλ‹€. 각 ν…ŒμŠ€νŠΈλ§ˆλ‹€ 독립적인 ν™˜κ²½μ„ λ§Œλ“€μ–΄ 병렬 μ‹€ν–‰ μ‹œμ—λ„ μ•ˆμ •μ μΈ ν…ŒμŠ€νŠΈλ₯Ό κ°€λŠ₯ν•˜κ²Œ ν•˜λ©°, νŠΉμ • μ—”λ“œν¬μΈνŠΈμ— λŒ€ν•΄ 성곡 ν˜Ήμ€ μ‹€νŒ¨, 그리고 λ¦¬ν„΄κ°’κΉŒμ§€ μ •ν•΄μ„œ 보내쀄 수 μžˆμŠ΅λ‹ˆλ‹€.

import { http, HttpResponse } from 'msw';

import { server } from '../setupTests';
import type { Event } from '../types';

export const setupMockHandlerCreation = (initEvents = [] as Event[]) => {
  const mockEvents: Event[] = [...initEvents];

  server.use(
    http.get('/api/events', () => {
      return HttpResponse.json({ events: mockEvents });
    }),
    http.post('/api/events', async ({ request }) => {
      const newEvent = (await request.json()) as Event;
      newEvent.id = String(mockEvents.length + 1); // κ°„λ‹¨ν•œ ID 생성
      mockEvents.push(newEvent);
      return HttpResponse.json(newEvent, { status: 201 });
    })
  );
};

Q. setupTests.ts > μ™œ 이 μ‹œκ°„μ„ μ„€μ •ν•΄μ£ΌλŠ” κ±ΈκΉŒμš”?

beforeEach(() => {
  expect.hasAssertions(); // ? Med: 이걸 μ™œ μ¨μ•Όν•˜λŠ”μ§€ λ¬Όμ–΄λ³΄μž
  vi.setSystemTime(new Date('2025-10-01')); // ? Med: 이걸 μ™œ μ¨μ•Όν•˜λŠ”μ§€ λ¬Όμ–΄λ³΄μž
  resetEvents();
});

λͺ¨λ“  ν…ŒμŠ€νŠΈκ°€ λ™μΌν•œ κΈ°μ€€ λ‚ μ§œ(2025-10-01)λ₯Ό μ‚¬μš©ν•˜λ„λ‘ 보μž₯ν•˜μ—¬ μ‹œκ°„ 의쑴적인 λ‘œμ§μ„ μ•ˆμ •μ μœΌλ‘œ ν…ŒμŠ€νŠΈν•  수 있게 ν•©λ‹ˆλ‹€. νƒ€μž„μ‘΄μ˜ μ°¨μ΄λ‚˜ μ‹€μ œ μ‹€ν–‰μ‹œμ μ΄ λ‹¬λΌμ„œ λ°œμƒν•˜λŠ” ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€λ₯Ό μ œκ±°ν•˜κΈ° μœ„ν•œ μ„€μ •μž…λ‹ˆλ‹€.

κ΄€λ ¨ λ‚΄μš© 정리본

심화 과제

  • App μ»΄ν¬λ„ŒνŠΈ μ μ ˆν•œ λ‹¨μœ„μ˜ μ»΄ν¬λ„ŒνŠΈ, ν›…, μœ ν‹Έ ν•¨μˆ˜λ‘œ λΆ„λ¦¬ν–ˆλŠ”κ°€?
  • ν•΄λ‹Ή λͺ¨λ“ˆλ“€μ— λŒ€ν•œ μ μ ˆν•œ ν…ŒμŠ€νŠΈλ₯Ό 5개 이상 μž‘μ„±ν–ˆλŠ”κ°€?

과제 μ…€ν”„νšŒκ³ 

이번 과제λ₯Ό 톡해 ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±μ˜ 전체적인 흐름을 κ²½ν—˜ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλ™μ•ˆ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μ‹€μ œλ‘œ 써본 적이 μ—†μ–΄μ„œ Medium λ‚œμ΄λ„λ₯Ό μ„ νƒν–ˆλŠ”λ°, 결과적으둜 λͺ©ν‘œμ˜€λ˜ λͺ¨λ“  ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό μž‘μ„±ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. ν…ŒμŠ€νŠΈ μž‘μ„±λΏλ§Œ μ•„λ‹ˆλΌ μ»΄ν¬λ„ŒνŠΈ 뢄리 μž‘μ—…κΉŒμ§€ ν•¨κ»˜ ν•˜λ©΄μ„œ μž¬λ―ΈμžˆλŠ” κ³Όμ œκ°€ λ˜μ—ˆλ˜κ±° κ°™μ•„μš”

기술적 μ„±μž₯

이번 과제λ₯Ό 톡해 React Testing Library의 핡심 κ°œλ…μΈ getBy, queryBy, findBy의 차이점과 ν™œμš©λ²•μ„ 배울 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. MSWλ₯Ό ν†΅ν•œ API λͺ¨ν‚Ήκ³Ό λ„€νŠΈμ›Œν¬ μš”μ²­ κ°€λ‘œμ±„κΈ° ν•˜λŠ” 방법도 써볼 수 μžˆμ—ˆκ³ , μ»΄ν¬λ„ŒνŠΈ λ‹¨μœ„ ν…ŒμŠ€νŠΈμ™€ 톡합 ν…ŒμŠ€νŠΈμ˜ 차이점을 μ‹€μ œλ‘œ κ΅¬ν˜„ν•˜λ©΄μ„œ μ–΄λŠμ •λ„ 감을 μž‘μ„ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

κ΅¬ν˜„ν•˜λ©΄μ„œ μ–΄λ €μ› λ˜ 건 MUI μ»΄ν¬λ„ŒνŠΈ ν…ŒμŠ€νŠΈν•  λ•Œ μ˜¬λ°”λ₯Έ selectorλ₯Ό κ³ λ₯΄λŠ” κ²ƒμ΄μ˜€λŠ”λ°, aria-labelκ³Ό role 속성을 잘 ν™œμš©ν•΄μ„œ 접근성을 κ³ λ €ν•œ ν…ŒμŠ€νŠΈ μž‘μ„±λ²•μ„ μ‚¬μš©ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

μ½”λ“œ ν’ˆμ§ˆ

μ½”λ“œ ν’ˆμ§ˆμ„ 높이기 μœ„ν•΄μ„œ ν…ŒμŠ€νŠΈλ₯Ό λ¨Όμ € 짜고 κ·Έ λ‹€μŒμ— μ»΄ν¬λ„ŒνŠΈλ₯Ό μͺΌκ°œλŠ” λ°©μ‹μœΌλ‘œ μ§„ν–‰ν–ˆμŠ΅λ‹ˆλ‹€. ν…ŒμŠ€νŠΈκ°€ κΉ¨μ§€μ§€ μ•ŠλŠ” μ„ μ—μ„œ μ‘°κΈˆμ”© μ»΄ν¬λ„ŒνŠΈλ₯Ό λΆ„λ¦¬ν•΄λ‚˜κ°”μŠ΅λ‹ˆλ‹€.

λ¬Όλ‘  아직 λΆ€μ‘±ν•œ 뢀뢄도 λ§Žμ€λ°μš”.. μ»΄ν¬λ„ŒνŠΈλ₯Ό λ‚˜λˆ„λ‹€ λ³΄λ‹ˆ propsλ₯Ό μ—¬λŸ¬ λ‹¨κ³„λ‘œ λ‚΄λ €μ£ΌλŠ” 일이 λ§Žμ•„μ‘Œκ³ , ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μ€‘μ—λŠ” λΉ„μŠ·ν•œ 둜직이 μ€‘λ³΅λ˜λŠ” 것듀도 μžˆμ–΄μ„œ 정리가 ν•„μš”ν•œ κ±° κ°™μŠ΅λ‹ˆλ‹€.

ν•™μŠ΅ 효과 뢄석

이번 κ³Όμ œμ—μ„œ κ°€μž₯ 크게 얻어간건 ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±μ˜ 전체적인 흐름을 μ΄ν•΄ν•œ κ²ƒμž…λ‹ˆλ‹€. κ·Έλƒ₯ κΈ°λŠ₯이 잘 λŒμ•„κ°€λŠ”μ§€λ§Œ 보던 κ²ƒμ—μ„œ λ²—μ–΄λ‚˜μ„œ, μ‹€μ œλ‘œ μ‚¬μš©μžκ°€ μ“°λŠ” κ΄€μ μ—μ„œ μ»΄ν¬λ„ŒνŠΈκ°€ μ œλŒ€λ‘œ λ™μž‘ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” 방법을 λ°°μ› κ³  μ•žμœΌλ‘œ κ°œλ°œν•  λ•Œ κΈ°νšŒκ°€ λœλ‹€λ©΄ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό 톡해 μ½”λ“œ ν’ˆμ§ˆλ„ 높일 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€

아직 더 곡뢀해야 ν•  뢀뢄듀도 λ§Žμ€ κ±° κ°™μŠ΅λ‹ˆλ‹€ λ³΅μž‘ν•œ μƒνƒœ 관리가 μžˆλŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό μ–΄λ–»κ²Œ ν…ŒμŠ€νŠΈν• μ§€, E2E ν…ŒμŠ€νŠΈμ™€ λ‹¨μœ„ ν…ŒμŠ€νŠΈλ₯Ό μ–΄λ–€ λΉ„μœ¨λ‘œ 써야 ν• μ§€, ν…ŒμŠ€νŠΈ 컀버리지와 μ‹€μ œ ν’ˆμ§ˆ μ‚¬μ΄μ˜ μ μ ˆν•œ 선을 μ–΄λ–»κ²Œ 찾을지 같은 것듀.... μ—­μ‹œ μ‹€μ œλ‘œ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό 많이 μ§œλ΄μ•Ό μ•Œ κ±° κ°™μ•„μš”

과제 ν”Όλ“œλ°±

κ³Όμ œμ—μ„œ μ’‹μ•˜λ˜ 뢀뢄은 ν…ŒμŠ€νŠΈ 처음 ν•˜λŠ” μ‚¬λžŒμ„ μœ„ν•΄ μ—¬λŸ¬ λ‚œμ΄λ„κ°€ μžˆλ‹€λŠ” μ μž…λ‹ˆλ‹€. μ €λŠ” Medium λ‚œμ΄λ„λ₯Ό 톡해 μœ λ‹› ν…ŒμŠ€νŠΈλΆ€ν„° μ‹œμž‘ν•΄μ„œ 톡합 ν…ŒμŠ€νŠΈκΉŒμ§€ μžμ—°μŠ€λŸ½κ²Œ 배울 수 μžˆμ—ˆκ³ , μ‹€μ œ μ‚¬μš©μžκ°€ μ“°λŠ” μ‹œλ‚˜λ¦¬μ˜€λ‘œ λ§Œλ“  톡합 ν…ŒμŠ€νŠΈκ°€ μž¬λ―Έμžˆμ—ˆμŠ΅λ‹ˆλ‹€. 이런 μ‹μœΌλ‘œ λ‹¨κ³„λ³„λ‘œ μ ‘κ·Όν•˜λ‹ˆκΉŒ ν…ŒμŠ€νŠΈμ˜ 전체적인 흐름을 이해할 수 μžˆμ—ˆλ˜κ±° κ°™μ•„μš”

리뷰 λ°›κ³  싢은 λ‚΄μš©

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ λ²”μœ„μ— λŒ€ν•œ 고민이 μžˆμŠ΅λ‹ˆλ‹€ "μ»΄ν¬λ„ŒνŠΈκ°€ λ Œλ”λ§λ˜λŠ”κ°€" 같은 기본적인 ν…ŒμŠ€νŠΈλΆ€ν„° λ³΅μž‘ν•œ μ‚¬μš©μž μ‹œλ‚˜λ¦¬μ˜€κΉŒμ§€ λ‹€μ–‘ν•˜κ²Œ μž‘μ„±ν–ˆλŠ”λ°, μ–΄λŠ 정도 μ„ μ—μ„œ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•˜λŠ” 게 μ μ ˆν•œμ§€ κΆκΈˆν•©λ‹ˆλ‹€. 특히 λ‹¨μˆœν•œ λ Œλ”λ§ ν…ŒμŠ€νŠΈκ°€ μ‹€μ œλ‘œ μ˜λ―Έκ°€ μžˆλŠ” 건지, μ•„λ‹ˆλ©΄ μ’€ 더 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— 집쀑해야 ν•˜λŠ” 건지 아직 감을 잘λͺ»μž‘μ•˜μŠ΅λ‹ˆλ‹€...

ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ 쀑볡에 λŒ€ν•΄ κΆκΈˆν•œ 점도 μžˆμŠ΅λ‹ˆλ‹€! λΉ„μŠ·ν•œ λ‘œμ§μ„ ν…ŒμŠ€νŠΈν•˜λŠ” μΌ€μ΄μŠ€λ“€μ΄ μžˆλŠ”λ°, 이런 경우 ν…ŒμŠ€νŠΈλ₯Ό ν•©μΉ˜λŠ” 게 쒋을지 μ•„λ‹ˆλ©΄ 각각의 μΌ€μ΄μŠ€λ₯Ό λͺ…ν™•ν•˜κ²Œ κ΅¬λΆ„ν•΄μ„œ μœ μ§€ν•˜λŠ” 게 쒋을지 쑰언을 받아보고 μ‹ΆμŠ΅λ‹ˆλ‹€!

과제 ν”Όλ“œλ°±

μ•ˆλ…•ν•˜μ„Έμš” μ°¬κ·œλ‹˜! 7μ£Όμ°¨ 과제 잘 μ§„ν–‰ν•΄μ£Όμ…¨λ„€μš” γ…Žγ…Ž κ³ μƒν•˜μ…¨μŠ΅λ‹ˆλ‹€!!

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ λ²”μœ„μ— λŒ€ν•œ 고민이 μžˆμŠ΅λ‹ˆλ‹€ "μ»΄ν¬λ„ŒνŠΈκ°€ λ Œλ”λ§λ˜λŠ”κ°€" 같은 기본적인 ν…ŒμŠ€νŠΈλΆ€ν„° λ³΅μž‘ν•œ μ‚¬μš©μž μ‹œλ‚˜λ¦¬μ˜€κΉŒμ§€ λ‹€μ–‘ν•˜κ²Œ μž‘μ„±ν–ˆλŠ”λ°, μ–΄λŠ 정도 μ„ μ—μ„œ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•˜λŠ” 게 μ μ ˆν•œμ§€ κΆκΈˆν•©λ‹ˆλ‹€. 특히 λ‹¨μˆœν•œ λ Œλ”λ§ ν…ŒμŠ€νŠΈκ°€ μ‹€μ œλ‘œ μ˜λ―Έκ°€ μžˆλŠ” 건지, μ•„λ‹ˆλ©΄ μ’€ 더 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— 집쀑해야 ν•˜λŠ” 건지 아직 감을 잘λͺ»μž‘μ•˜μŠ΅λ‹ˆλ‹€...

https://discord.com/channels/1288769861589270590/1369931229696229386/1408221063317295295

μ˜€ν”„ μ½”μΉ˜λ‹˜κ»˜μ„œ λ‚¨κ²¨μ£Όμ‹œκΈ΄ ν–ˆλŠ”λ°, μ €λŠ” λŒ€μ²΄λ‘œ μ»΄ν¬λ„ŒνŠΈμ— λŒ€ν•œ λ Œλ”λ§ ν…ŒμŠ€νŠΈλŠ” λ¬΄μ˜λ―Έν•˜λ‹€κ³  μƒκ°ν•΄μš” γ…Žγ…Ž μ»΄ν¬λ„ŒνŠΈλŠ” "데이터λ₯Ό ν‘œν˜„ν•˜λŠ” μˆ˜λ‹¨"이고, κ·Έλ ‡λ‹€λ©΄ λ°μ΄ν„°μ˜ output에 λŒ€ν•œ 검증을 ν•  수 μžˆλ‹€λ©΄ μ»΄ν¬λ„ŒνŠΈλ„ μžμ—°μŠ€λŸ½κ²Œ κ²€μ¦λ˜λŠ”κ²Œ λ§Žλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λ‹€λ§Œ μΈν„°λž™μ…˜μ„ μ»΄ν¬λ„ŒνŠΈκ°€ μ—°κ²°ν•΄μ£ΌκΈ° λ•Œλ¬Έμ— μΈν„°λž™μ…˜ 연결이 μžμ—°μŠ€λŸ¬μš΄μ§€μ— λŒ€ν•΄μ„œλŠ” μ»΄ν¬λ„ŒνŠΈ λ ˆμ΄μ–΄μ—μ„œ ν…ŒμŠ€νŠΈν•΄λ³Ό 수 있겠죠!? λ‹€λ§Œ 이게 vitest 처럼 nodejs ν™˜κ²½μ—μ„œ κ²€μ¦ν•˜λŠ”κ²Œ λŒ€μ²΄λ‘œ μ–΄λ €μ–΄μš”. κ·Έλž˜μ„œ μ»΄ν¬λ„ŒνŠΈ λ ˆμ΄μ–΄μ— λŒ€ν•œ ν…ŒμŠ€νŠΈκ°€ ν•„μš”ν•˜λ‹€λ©΄ μ•„μ˜ˆ e2e ν…ŒμŠ€νŠΈλ₯Ό 해보면 μ–΄λ–¨κΉŒ!? λΌλŠ” μƒκ°μž…λ‹ˆλ‹€.

결둠은, λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— 쑰금 더 μ΄ˆμ μ„ λ§žμΆ°μ„œ ν…ŒμŠ€νŠΈ ν•΄μ£Όμ‹œλ©΄ μ’‹κ² λ‹€λŠ” μƒκ°μž…λ‹ˆλ‹€!

ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ 쀑볡에 λŒ€ν•΄ κΆκΈˆν•œ 점도 μžˆμŠ΅λ‹ˆλ‹€! λΉ„μŠ·ν•œ λ‘œμ§μ„ ν…ŒμŠ€νŠΈν•˜λŠ” μΌ€μ΄μŠ€λ“€μ΄ μžˆλŠ”λ°, 이런 경우 ν…ŒμŠ€νŠΈλ₯Ό ν•©μΉ˜λŠ” 게 쒋을지 μ•„λ‹ˆλ©΄ 각각의 μΌ€μ΄μŠ€λ₯Ό λͺ…ν™•ν•˜κ²Œ κ΅¬λΆ„ν•΄μ„œ μœ μ§€ν•˜λŠ” 게 쒋을지 쑰언을 받아보고 μ‹ΆμŠ΅λ‹ˆλ‹€!

κ²€μ¦ν•˜λŠ” μ½”λ“œλ₯Ό μ•„μ˜ˆ ν•¨μˆ˜λ‘œ λΆ„λ¦¬ν•΄μ£Όμ‹œλ©΄ μ’‹λ‹΅λ‹ˆλ‹€ γ…Žγ…Ž

이런 λŠλ‚Œμ΄μ£ .

test('일정 μΆ”κ°€ ν…ŒμŠ€νŠΈ', () => {
  νΌμž…λ ₯_검증();
  폼저μž₯_검증();
  λͺ©λ‘ν™•인_검증();
})