[3ํ ์ด๊ฐ์] Chapter ๐ฆ 3-1. ํ๋ก ํธ์๋ ํ ์คํธ ์ฝ๋ ๐ฆ#53
[3ํ ์ด๊ฐ์] Chapter ๐ฆ 3-1. ํ๋ก ํธ์๋ ํ
์คํธ ์ฝ๋ ๐ฆ#53tooth-is-silver wants to merge 26 commits intohanghae-plus:mediumfrom
Conversation
susmisc14
left a comment
There was a problem hiding this comment.
์๋
ํ์ธ์! AI ์ฝ๋ ๋ฆฌ๋ทฐ์ด์
๋๋ค. ๐ค
[FE] 7์ฃผ์ฐจ ๊ณผ์ : ํ
์คํธ ์ฝ๋ ๊ธฐ์ด Pull Request์ ๋ํ ๋ฆฌ๋ทฐ๋ฅผ ์๋ฃํ์ด์. ํจ๊ป ์ฝ๋๋ฅผ ๋ ๋ฐ์ ์์ผ ๋ณผ๊น์?
Note
โจ ์ด๋ฒ PR ํ ์ค ์์ฝ
๊ฑฐ๋ํ App ์ปดํฌ๋ํธ๋ฅผ ํ
์คํธ ์ฉ์ด์ฑ์ด ๋์ ์ปดํฌ๋ํธ์ ํ
์ผ๋ก ์ฑ๊ณต์ ์ผ๋ก ๋ถ๋ฆฌํ๊ณ , ๊ฒฌ๊ณ ํ ๋จ์/ํตํฉ ํ
์คํธ๋ฅผ ๊ตฌ์ถํ์ฌ ์ฝ๋์ ์ ๋ขฐ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ํฌ๊ฒ ํฅ์์์ผฐ์ต๋๋ค.
๐ฏ ํต์ฌ ๋ฆฌ๋ทฐ ์์ฝ
๊ฐ์ฅ ์ค์ํ ๊ฐ์ ํฌ์ธํธ๋ถํฐ ๋น ๋ฅด๊ฒ ํ์ธํด ๋ณด์ธ์.
- ์ํคํ
์ฒ ๊ฐ์ : 'God Component'์๋
App.tsx๋ฅผ ๋ชฉ์ ์ ๋ฐ๋ผ ์ปดํฌ๋ํธ์ ํ ์ผ๋ก ๋ถ๋ฆฌํ ๊ฒ์ ์ด๋ฒ ๊ณผ์ ์ ๊ฐ์ฅ ํฐ ์ฑ๊ณผ์ ๋๋ค. ์ด๋ ํ ์คํธ ์ฉ์ด์ฑ์ ๊ทน์ ์ผ๋ก ํฅ์์์ผฐ์ต๋๋ค. - ํ ์คํธ ๋ฐ์ดํฐ ๊ด๋ฆฌ: ํ ์คํธ์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ํ ๋จ๊ณ ๋ ๋์ด์ฌ๋ฆด ์ ์๋ 'ํ ์คํธ ๋ฐ์ดํฐ ํฉํ ๋ฆฌ(Factory) ํจํด' ๋์ ์ ์ ์ํฉ๋๋ค.
- ํ ์คํธ ์ ๋ต: ํตํฉ ํ ์คํธ์ ๋จ์ ํ ์คํธ์ ์ด์์ ์ธ ๊ท ํ์ ๋ํ ๊ณ ๋ฏผ์ 'ํ ์คํ ํธ๋กํผ(The Testing Trophy)' ๊ฐ๋ ์ ํตํด ํด๊ฒฐํด ๋ณด์ธ์.
- ํ
์คํธ ๊ฐ๋
์ฑ:
it.skip๊ณผ ๊ฐ์ด ๋นํ์ฑํ๋ ํ ์คํธ ์ผ์ด์ค๋ ๊ทธ ์ด์ ๋ฅผ ๋ช ํํ ๋ฌธ์ํํ์ฌ ํ์ ํผ๋์ ๋ฐฉ์งํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๐ ์์ธ ๋ฆฌ๋ทฐ
๊ฐ ํญ๋ชฉ์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์ค๋ช ๊ณผ ์ฝ๋ ์์๋ฅผ ์ค๋นํ์ด์.
1. ๊ฒฝ์ด๋ก์ด ๋ฆฌํฉํ ๋ง: God Component์ ํด์ฒด์ ํ ์คํธ ๊ฐ๋ฅํ ์ํคํ ์ฒ ๊ตฌ์ถ
- ๐ ์ข์ ์ :
App.tsxํ๋์ ๋ชจ๋ ์ํ, ๋ก์ง, UI๊ฐ ๋ค์์ฌ ์๋ ๊ตฌ์กฐ๋ฅผuseEventHandlers,useCalendarView๊ฐ์ ์ปค์คํ ํ ๊ณผEventForm,CalendarView๋ฑ์ ํ๋ ์ ํ ์ด์ ๋ ์ปดํฌ๋ํธ๋ก ์๋ฒฝํ๊ฒ ๋ถ๋ฆฌํด๋ด์ จ์ต๋๋ค. ์ด ๊ฒฐ์ ๋๋ถ์ ๊ฐ ๋ชจ๋์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ๊ณ ์ ์ง๋ณด์ํ๋ ๊ฒ์ด ๋งค์ฐ ์ฉ์ดํด์ก์ต๋๋ค. ์ ํ ํ๊ณ ์์ "์์ง๋๊ฐ ๋๊ณ ๊ฒฐํฉ๋๊ฐ ๋ฎ์ ์ฝ๋์ผ์๋ก ํ ์คํธ ์ฝ๋ ์์ฑ์ด ํจ์ฌ ์์ํ๋ค"๊ณ ๋ง์ํ์ ๋ถ๋ถ์ ์ฝ๋๋ก ์ง์ ์ฆ๋ช ํด๋ด์ จ๋ค์. - ๐ก ๊ฐ์ ์ ์: ํ์ฌ ๊ตฌ์กฐ์ ์ฐ์์ฑ์ ๋ช ํํ ์ดํดํ๊ณ , ์์ผ๋ก๋ ์ด๋ฐ ์ค๊ณ๋ฅผ ์ ์งํ๊ธฐ ์ํด '์์ง๋'์ '๊ฒฐํฉ๋'์ ๊ฐ๋ ์ ๋ค์ ํ๋ฒ ์ง์ด๋ณด๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค.
- ๐ค ์ด๋ ๊ฒ ์ ์ํ๋ ์ด์ :
- ๋์ ์์ง๋ (High Cohesion):
useEventOperations๋ ์๋ฒ ํต์ ๋ง,useEventForm์ ํผ ์ํ ๊ด๋ฆฌ๋ง ์ฑ ์์ง๋๋ค. ์ด๋ ๊ฒ ํ๋์ ๋ชจ๋์ด ํ๋์ ์ฑ ์๋ง ๊ฐ๊ฒ ๋๋ฉด ์ฝ๋๋ฅผ ์ดํดํ๊ณ ํ ์คํธํ๊ธฐ๊ฐ ๋งค์ฐ ์ฌ์์ง๋๋ค. - ๋ฎ์ ๊ฒฐํฉ๋ (Low Coupling):
EventList์ปดํฌ๋ํธ๋ ์ด์ events๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ์์ฑ๋๊ณ ๊ด๋ฆฌ๋๋์ง ์ ํ์ ์์ด, ๊ทธ์ props๋ก ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ณ ์ํธ์์ฉ(์์ /์ญ์ )์ ๋ถ๋ชจ์๊ฒ ์๋ฆฌ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ด๋EventList์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ ,App.tsx์ ๋ณ๊ฒฝ์ดEventList์ ๋ฏธ์น๋ ์ํฅ์ ์ต์ํํฉ๋๋ค.
- ๋์ ์์ง๋ (High Cohesion):
- ๐ป ์ํคํ ์ฒ ๋น๊ต (AS-IS vs TO-BE)
AS-IS: ํ๋์ ๊ฑฐ๋ํ App ์ปดํฌ๋ํธ
graph TD
A[App.tsx]
A --> B{State (useState)}
A --> C{API Logic (fetch, etc.)}
A --> D{UI Rendering (JSX)}
A --> E{Event Handlers}
A --> F{Side Effects (useEffect)}
TO-BE: ์ญํ ๊ณผ ์ฑ ์์ ๋ฐ๋ผ ๋ถ๋ฆฌ๋ ๊ตฌ์กฐ
graph TD
subgraph Components
D1[EventForm]
D2[CalendarView]
D3[EventList]
end
subgraph Hooks
B1[useEventForm]
B2[useCalendarView]
C1[useEventOperations]
E1[useEventHandlers]
end
A[App.tsx] --> B1 & B2 & C1 & E1
A --> D1 & D2 & D3
B1 --> D1
B2 & C1 --> D2
C1 --> D3
์ด์ฒ๋ผ ์ญํ ์ ๋ฐ๋ผ ๋ชจ๋์ ๋ถ๋ฆฌํ๋ ๊ฒ์ ํ ์คํธ ์ฉ์ด์ฑ์ ๋์ด๋ ์ฒซ๊ฑธ์์ด์ ๊ฐ์ฅ ์ค์ํ ๋จ๊ณ์ ๋๋ค. ํ๋ฅญํ ๋ฆฌํฉํ ๋ง์ ๋๋ค!
2. ํ ์คํธ ๋ฐ์ดํฐ ๊ด๋ฆฌ: ๋ ์ด์ ํ๋์ฝ๋ฉ์ ๊ทธ๋ง, 'ํฉํ ๋ฆฌ ํจํด'์ผ๋ก ์งํํ๊ธฐ
-
๐ ์ข์ ์ : ํ ์คํธ ์ผ์ด์ค๋ง๋ค ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ ์ํ์ฌ ๊ฐ ํ ์คํธ์ ๋ ๋ฆฝ์ฑ์ ํ๋ณดํ๋ ค๋ ๋ ธ๋ ฅ์ด ๋ณด์ ๋๋ค. "ํ ์คํธ๋ณ๋ก ํ์ํ ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๋ ๊ฒ์ด ๊ฐ๋ ์ฑ ๋ฉด์์ ๋ ์ข๋ค๊ณ ํ๋จํ๋ค"๋ ๊ณ ๋ฏผ์ ๋งค์ฐ ์ค์ํ๊ณ ์ข์ ์ถ๋ฐ์ ์ ๋๋ค.
-
๐ก ๊ฐ์ ์ ์: ํ๋ก์ ํธ๊ฐ ์ปค์ง ๊ฒ์ ๋๋นํด, ๋ฐ๋ณต์ ์ธ ๋ชจํน(Mocking) ๋ฐ์ดํฐ ์์ฑ์ ์ถ์ํํ๋ ํ ์คํธ ๋ฐ์ดํฐ ํฉํ ๋ฆฌ(Test Data Factory) ํจํด์ ๋์ ํด ๋ณด์ธ์. ์ด ํจํด์ ํ ์คํธ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๊ทน์ ์ผ๋ก ํฅ์์ํต๋๋ค.
-
๐ค ์ด๋ ๊ฒ ์ ์ํ๋ ์ด์ :
- ๊ฐ๋
์ฑ ํฅ์:
createMockEvent({ title: '์ค์ํ ํ์' })์ฒ๋ผ ํ ์คํธ์ ํ์์ ์ธ ๋ฐ์ดํฐ๋ง ๋ช ์ํ๋ฉด, ์ด ํ ์คํธ๊ฐ ๋ฌด์์ ๊ฒ์ฆํ๋ ค๋์ง ์๋๊ฐ ๋ช ํํด์ง๋๋ค. ๋๋จธ์ง ์์ฑ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์์ง๋ฏ๋ก ํ ์คํธ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๋๋ค. - ์ ์ง๋ณด์ ์ฉ์ด์ฑ:
Eventํ์ ์ ์๋ก์ด ํ๋(์:priority)๊ฐ ์ถ๊ฐ๋ ๋, ๋ชจ๋ ํ ์คํธ ํ์ผ์ ์์ ํ ํ์ ์์ด ํฉํ ๋ฆฌ ํจ์ ํ ๊ณณ๋ง ์์ ํ๋ฉด ๋ฉ๋๋ค. ์ด๋ ์์ญ, ์๋ฐฑ ๊ฐ์ ํ ์คํธ๋ฅผ ๊ด๋ฆฌํ ๋ ์์ฒญ๋ ์๊ฐ ์ ์ฝ์ผ๋ก ์ด์ด์ง๋๋ค.
- ๊ฐ๋
์ฑ ํฅ์:
-
๐ป ์ฝ๋ ์์ (AS-IS vs TO-BE)
AS-IS (
medium.useEventOperations.spec.ts)
it('์ด๋ฒคํธ ์ ๋ณด๋ฅผ ๋ฐ์ ๊ธฐ์กด ์ด๋ฒคํธ ๋ฐฐ์ด์ ์ ์์ ์ผ๋ก ์ ์ฅ์ด ๋๋ค', async () => {
// ...
const newEvent: Event = {
id: '1',
title: '์๋ก์ด ํ์',
date: '2025-07-16',
startTime: '12:00',
endTime: '13:00',
description: '์๋ก์ด ํ ๋ฏธํ
',
location: 'ํ์์ค D',
category: '์
๋ฌด',
repeat: { type: 'none', interval: 0 },
notificationTime: 15,
};
// ...
});
```
TO-BE (ํ
์คํธ ์ ํธ๋ฆฌํฐ ํ์ผ์ ํฉํ ๋ฆฌ ํจ์ ์์ฑ)
```typescript
// src/__tests__/utils/factory.ts
import { Event } from '../../types';
export const createMockEvent = (overrides: Partial<Event> = {}): Event => {
return {
id: 'default-id-' + Math.random(),
title: '๊ธฐ๋ณธ ์ ๋ชฉ',
date: '2025-10-01',
startTime: '10:00',
endTime: '11:00',
description: '๊ธฐ๋ณธ ์ค๋ช
',
location: '๊ธฐ๋ณธ ์์น',
category: '์
๋ฌด',
repeat: { type: 'none', interval: 1 },
notificationTime: 10,
...overrides, // ์ฌ๊ธฐ์ ํ์ํ ์์ฑ๋ง ๋ฎ์ด์๋๋ค.
};
};
```
(ํ
์คํธ ํ์ผ์์ ์ฌ์ฉ)
```typescript
// medium.useEventOperations.spec.ts
import { createMockEvent } from '../utils/factory';
it('์ ๋ชฉ์ด ๋ค๋ฅธ ์๋ก์ด ์ด๋ฒคํธ๊ฐ ์ ์์ ์ผ๋ก ์ ์ฅ๋๋ค', async () => {
// ...
// ์ด์ ์ด ํ
์คํธ์ ํต์ฌ์ธ 'title'๊ณผ 'description'๋ง ์ ๊ฒฝ์ฐ๋ฉด ๋ฉ๋๋ค.
const newEvent = createMockEvent({
id: '1',
title: '์๋ก์ด ํ์',
description: '์๋ก์ด ํ ๋ฏธํ
',
});
// ...
});
```
**3. ํ
์คํธ ์ ๋ต ์๋ฆฝ: Kent C. Dodds์ 'ํ
์คํ
ํธ๋กํผ'๋ฅผ ์์๋์?**
- **๐ ์ข์ ์ **: "ํตํฉํ
์คํธ vs ๋จ์ํ
์คํธ ๋น์จ๊ณผ ์ ๋ต"์ ๋ํด ๊น์ด ๊ณ ๋ฏผํ๊ณ ์ง๋ฌธํด์ฃผ์ ์ ์ด ๋งค์ฐ ์ธ์ ๊น์ต๋๋ค. ์ด๋ ๋ชจ๋ ๊ฐ๋ฐ์๊ฐ ๋ถ๋ชํ๋ ํ์ค์ ์ธ ๊ณ ๋ฏผ์ด๋ฉฐ, ์ด ๊ณ ๋ฏผ ์์ฒด๊ฐ ์ฑ์ฅ์ ์ฆ๊ฑฐ์
๋๋ค.
- **๐ก ๊ฐ์ ์ ์**: ๋จ์ ํ
์คํธ์ ํตํฉ ํ
์คํธ์ ๊ด๊ณ๋ฅผ ๊ฒฝ์์ด ์๋ ํ๋ ฅ ๊ด๊ณ๋ก ๋ฐ๋ผ๋ณด๋ **'ํ
์คํ
ํธ๋กํผ(The Testing Trophy)'** ๋ชจ๋ธ์ ์๊ฐํด ๋๋ฆฌ๊ณ ์ถ์ต๋๋ค. ์ด ๋ชจ๋ธ์ '์ผ๋ง๋ ๋ง์ ๋น์ฉ์ ๋ค์ฌ ์ผ๋ง๋ ํฐ ์์ ๊ฐ์ ์ป์ ๊ฒ์ธ๊ฐ?'์ ๋ํ ํ๋ฅญํ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
- **๐ค ์ด๋ ๊ฒ ์ ์ํ๋ ์ด์ **:
- **๋จ์ ํ
์คํธ(Unit Tests)**: ๋น ๋ฅด๊ณ , ์ ๋ ดํ๋ฉฐ, ํน์ ๋ก์ง์ ์ ํ์ฑ์ ๊ฒ์ฆํฉ๋๋ค. `dateUtils`์ ํจ์๋ค์ด ๋ํ์ ์ธ ์์์
๋๋ค. ํ์ง๋ง ๊ฐ ๋ถํ์ด ์ ์์ด๋ผ๊ณ ํด์ ์์ฑ๋ ์๋์ฐจ๊ฐ ์ ๊ตด๋ฌ๊ฐ๋ค๋ ๋ณด์ฅ์ ์์ต๋๋ค.
- **ํตํฉ ํ
์คํธ(Integration Tests)**: ์ฌ๋ฌ ๋ชจ๋(์ปดํฌ๋ํธ, ํ
, API ๋ฑ)์ด ํจ๊ป ๋์ํ๋ ๊ฒ์ ๊ฒ์ฆํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๊ฒฝํํ๋ ์ค์ ์๋๋ฆฌ์ค์ ๊ฐ์ฅ ๊ฐ๊น๊ธฐ ๋๋ฌธ์ **๊ฐ์ฅ ๋์ ROI(ํฌ์ ๋๋น ํจ๊ณผ)**๋ฅผ ์ ๊ณตํฉ๋๋ค. "์ผ์ ์ถ๊ฐ ๋ฒํผ์ ๋๋ฅด๋ฉด, API ์์ฒญ์ด ๊ฐ๊ณ , ๋ชฉ๋ก์ด ๊ฐฑ์ ๋๋ค"์ ๊ฐ์ ์๋๋ฆฌ์ค๋ฅผ ํ
์คํธํ๋ ๊ฒ์ด์ฃ .
- ํ๊ณ ๋ก์์ ์ธ๊ธํ์ "ํ
์คํธ ์ฝ๋๋ฅผ ๋ชจ๋ ํต๊ณผํ๋๋ฐ๋ ๋ถ๊ตฌํ๊ณ ํฌ๊ฒ ์๋ฌ๊ฐ ํฐ์ง ์ "์ด ๋ฐ๋ก ๋จ์ ํ
์คํธ๋ง์ผ๋ก๋ ๋ถ์กฑํ ๋ถ๋ถ์ ํตํฉ ํ
์คํธ๊ฐ ์ฑ์์ฃผ๋ ์ด์ ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์๋ฒฝํ ์ฌ๋ก์
๋๋ค.
- **๐ป ๋ค์ด์ด๊ทธ๋จ: The Testing Trophy**
/\\
/ \\ <- E2E (๊ฐ์ฅ ์ ๊ฒ)
/____\\
/ \\
/ \\ <- Integration (๊ฐ์ฅ ๋ง์ด, ํต์ฌ)
/__________\\
/ \\
/ \ <- Unit (์ค๊ฐ)
/________________\
/ \
Static Analysis (๊ธฐ๋ณธ)
```
์ด ๋ชจ๋ธ์ฒ๋ผ, ๋๋ถ๋ถ์ ๋
ธ๋ ฅ์ **ํตํฉ ํ
์คํธ**์ ์๋ ๊ฒ์ด ๋ฒ๊ทธ๋ฅผ ์ค์ด๊ณ ์์ ์ ์ธ ์๋น์ค๋ฅผ ๋ง๋๋ ๋ฐ ๊ฐ์ฅ ํจ๊ณผ์ ์
๋๋ค. ๋จ์ ํ
์คํธ๋ก ํตํฉ ํ
์คํธ๋ฅผ ๋์ฒดํ๋ ๊ฒ์ ์ํํ๋ฉฐ, "๋จ์ ํ
์คํธ์์ ์ต๋ํ ์ปค๋ฒํ๊ณ ํตํฉ ํ
์คํธ์์๋ UI์ ์ธ ๋ถ๋ถ๋ง ํ
์คํธ"ํ๋ ์ ๊ทผ๋ณด๋ค๋, ์ฌ์ฉ์์ ํต์ฌ ํ๋ฆ์ ๊ฒ์ฆํ๋ ํตํฉ ํ
์คํธ๋ฅผ ์ฐ์ ์ผ๋ก ์์ฑํ๊ณ , ๋ณต์กํ ์์ ํจ์ ๋ก์ง์ ๋จ์ ํ
์คํธ๋ก ๋ณด์ถฉํ๋ ์ ๋ต์ ์ถ์ฒํฉ๋๋ค.
๐บ๏ธ ์ ์ฒด ๊ฐ์ ๋ก๋๋งต (์ฐ์ ์์ ๊ฐ์ด๋)
ํผ๋๋ฐฑ์ ์ค์๋ ์์๋๋ก ์ ๋ ฌํ์ด์. ๋์ ์์๋ถํฐ ์ฐจ๊ทผ์ฐจ๊ทผ ํด๊ฒฐํด ๋๊ฐ๋ ๊ฑธ ์ถ์ฒํด์.
- CRITICAL ๐จ: ํ์ฌ ์ฝ๋์๋ ์ฌ๊ฐํ ๋ฒ๊ทธ๋ ๋ฌธ์ ๋ ๋ณด์ด์ง ์์ต๋๋ค. ํ๋ฅญํด์!
- WARNING
โ ๏ธ : ํ ์คํธ ๋ฐ์ดํฐ ํฉํ ๋ฆฌ ํจํด์ ๋์ ํ์ฌ ํ ์คํธ ์ฝ๋์ ์ ์ง๋ณด์์ฑ์ ํ๋ณดํ๋ ๊ฒ์ ์ ๊ทน ๊ถ์ฅํด์. ์ง๊ธ ๋น์ฅ์ ๊ด์ฐฎ์ง๋ง, ํ๋ก์ ํธ๊ฐ ๋ณต์กํด์ง๋ฉด ๊ธฐ์ ๋ถ์ฑ๋ก ๋์์ฌ ์ ์์ต๋๋ค. - OPTIONAL ๐ก:
it.skip์ผ๋ก ๋นํ์ฑํ๋ ํ ์คํธ(easy.eventUtils.spec.ts)์ ๋ํด, ์ ์คํตํ๋์ง ์ฃผ์(// ์์ ํ ์คํธ์ ์ค๋ณต๋์ด ๋นํ์ฑํ)์ ๋จ๊ฒจ๋๋ฉด ๋ฏธ๋์ ๋ ๋๋ ๋๋ฃ๊ฐ ์ฝ๋๋ฅผ ์ดํดํ๋ ๋ฐ ํฐ ๋์์ด ๋ฉ๋๋ค.
๐ค ํ ๊ฑธ์ ๋: ์ฝ๋์ ์๋ ๋์๋ณด๊ธฐ
PR ๋ณธ๋ฌธ์ ํตํด ๊น์ ๊ณ ๋ฏผ์ ์ฟ๋ณผ ์ ์์์ด์. ํ ์คํธ๋ผ๋ '์ ๋์ฝ'๊ณผ ๋ง์ด ์นํด์ง์ ๊ฒ ๊ฐ์ ์ ๋ ๊ธฐ์๋ค์! ์ฝ๋์ ํ๊ณ ๋ฅผ ๋น๊ตํ๋ฉฐ ๋ช ๊ฐ์ง ์ง๋ฌธ์ ์ค๋นํ์ต๋๋ค.
- ๋ชฉํ์ ๊ตฌํ์ ์ฐ๊ฒฐ๊ณ ๋ฆฌ: ๋ณธ๋ฌธ์ "App ์ปดํฌ๋ํธ ์ ์ ํ ๋จ์์ ์ปดํฌ๋ํธ, ํ
, ์ ํธ ํจ์๋ก ๋ถ๋ฆฌ"๋ผ๋ ๋ชฉํ๋ฅผ ์๋ฒฝํ๊ฒ ๋ฌ์ฑํ์
จ๋ค์. ํน์
useEventHandlersํ ์ ์ค๊ณํ ๋, ์ด๋ค ๋ก์ง๊น์ง ์ด ํ ์ ์ฑ ์์ผ๋ก ๋์ง ๊ณ ๋ฏผํ๋ ์ง์ ์ด ์๋์? ์๋ฅผ ๋ค์ดfindOverlappingEventsํธ์ถ์useEventHandlers๋ด๋ถ์์ ํ ์ง, ์ธ๋ถ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ฌ์ง ๊ฐ์ ๊ฒฐ์ ๋ค์ด์. - ์จ๊ฒจ์ง ์๋ ํ์
:
timeValidation.ts์TIME_FORMAT_REGEX๋ฅผ ์ถ๊ฐํ์ฌ ์๊ฐ ํ์ ์์ฒด๋ฅผ ๊ฒ์ฆํ๋ ๋ก์ง์ ์ถ๊ฐํ์ จ๋๊ตฐ์. ์๋ง ํ ์คํธ๋ฅผ ์์ฑํ์๋ฉด์ ๋ฐ๊ฒฌํ ์ฃ์ง ์ผ์ด์ค ๊ฐ์๋ฐ, ์ด๋ฐ ๋ํ ์ผ์ด ์ฝ๋์ ์์ ์ฑ์ ํฌ๊ฒ ๋์ ๋๋ค. ์ด๋ค ๊ณ๊ธฐ๋ก ์ด ๋ถ๋ถ์ ์ถ๊ฐํ๊ฒ ๋์ จ๋์ง ๊ถ๊ธํ๋ค์! - ์ค์ค๋ก์๊ฒ ๋์ง๋ ์ง๋ฌธ:
- ํ๊ณ ์์ TDD์ ์ค์์ฑ์ ๋๋ผ์
จ๋ค๊ณ ํ๋๋ฐ, ๋ง์ฝ
useEventHandlersํ ์ TDD ๋ฐฉ์์ผ๋ก ๊ฐ๋ฐํ๋ค๋ฉด ์ง๊ธ์ ์ฝ๋์ ์ด๋ป๊ฒ ๋ฌ๋ผ์ก์๊น์? ํ ์คํธ ์ผ์ด์ค๋ฅผ ๋จผ์ ์์ํด๋ณด๋ ์ฐ์ต์ ํด๋ณด๋ ๊ฑด ์ด๋จ๊น์? - Toss Frontend Fundamental์ ๊ฒฐํฉ๋(Coupling) ์์น์ ๋ณด๋ฉด "์ด๋ค ๋ชจ๋์ ๋ด์ฉ์ ๋ฐ๊ฟจ์ ๋ ๋ค๋ฅธ ๋ชจ๋์ ๋ ๊ณ ์ณ์ผ ํ๋ค๋ฉด, ๊ทธ ๋์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋์ด ์๋ค"๊ณ ๋งํฉ๋๋ค. ์ง๊ธ์ ๊ตฌ์กฐ์์ ๋ง์ฝ
notistack๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค๋ฅธ ์๋ฆผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๊ต์ฒดํ๋ค๋ฉด, ๋ช ๊ฐ์ ํ์ผ์ ์์ ํด์ผ ํ ๊น์? ์ด ์ง๋ฌธ์ด ๊ฒฐํฉ๋๋ฅผ ์ธก์ ํ๋ ์ข์ ์ฒ๋๊ฐ ๋ ์ ์์ต๋๋ค. - "์ด ์ฝ๋๋ฅผ ์ฒ์ ๋ณด๋ ๋๋ฃ๋
handlerUtils.ts์ ์ญํ ๊ณผsetupMockHandlerCreation๊ฐ์ ํจ์๋ค์ ๋์ ๋ฐฉ์์ ์ฝ๊ฒ ์ดํดํ ์ ์์๊น?" - ์ด๋ฒ์ ์ ์ฉํ ์ปดํฌ๋ํธ/ํ ๋ถ๋ฆฌ ์ํคํ ์ฒ๊ฐ "๋ฐ๋ณต ์ผ์ " ๊ฐ์ ๋ ๋ณต์กํ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋ ๋๋ ์ ์ฐํ๊ฒ ํ์ฅ๋ ์ ์์๊น์?
- ํ๊ณ ์์ TDD์ ์ค์์ฑ์ ๋๋ผ์
จ๋ค๊ณ ํ๋๋ฐ, ๋ง์ฝ
๐ ์ฐธ๊ณ ์๋ฃ
๋ฌธ์ ํด๊ฒฐ์ ๋์์ด ๋ ๋งํ ์๋ฃ๋ค์ ๋ชจ์๋ดค์ด์.
๐ ์ถ์ฒ ์ํฐํด
- The Testing Trophy and Testing Classifications: ์ ํตํฉ ํ ์คํธ๊ฐ ์ค์ํ์ง์ ๋ํ Kent C. Dodds์ ์๋ณธ ์ํฐํด์ ๋๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ์์ ํ ์คํธ ํฝ์ค์ณ๋ฅผ ๋ง๋๋ 5๊ฐ์ง ๋ฐฉ๋ฒ: ํ ์คํธ ๋ฐ์ดํฐ ํฉํ ๋ฆฌ ํจํด์ ํฌํจํ์ฌ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ค์ํ ์ ๋ต์ ์๊ฐํฉ๋๋ค.
- ๋ฆฌํฉํ ๋ง 2ํ: God Object๋ฅผ ๋ถํดํ๋ ๋ค์ฏ ๊ฐ์ง ๋จ๊ณ: ์ด๋ฒ์ ์ฑ๊ณต์ ์ผ๋ก ์ํํ์ God Component ๋ฆฌํฉํ ๋ง์ ๋ํ ์ฌ๋ ๊น์ ์ํฐํด์ ๋๋ค.
์ด๋ฒ ๋ฆฌ๋ทฐ๊ฐ ์ฑ์ฅ์ ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค! ํ ์คํธ ์ฝ๋์ ๋ํ ์ด์ ๊ณผ ๊น์ ๊ณ ๋ฏผ, ์ ๋ง ํ๋ฅญํฉ๋๋ค. ๊ณ์ ๋์๊ฐ์ธ์
There was a problem hiding this comment.
ํ ์คํธ ๋ฐ์ดํฐ ํธ์ถํ ๋ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด์ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋์ง ์ด๋ ต์ง ์๋ ์ถ๊ธฐ๋ ํ๋๋ฐ, ๊ทธ ํ ์คํธ ๋ก์ง์ด ์ผ๊ด์ฑ์ด ์์ด์ ์ฝ์ผ๋ฉด ์ฝ์์๋ก ๋น ๋ฅด๊ฒ ํ๋ฆ์ ํ์ ํ ์ ์์ด์ ์ข์์ต๋๋ค!
๋ค์ํ vitest ๋ฉ์๋ ์ฌ์ฉํด์ฃผ์ ์ ๋ง์ด ๋ฐฐ์ฐ๊ณ ๊ฐ๋๋น
|
|
||
| it("์ด๋ฒคํธ ๋ก๋ฉ ์คํจ ์ '์ด๋ฒคํธ ๋ก๋ฉ ์คํจ'๋ผ๋ ํ ์คํธ์ ํจ๊ป ์๋ฌ ํ ์คํธ๊ฐ ํ์๋์ด์ผ ํ๋ค", async () => {}); | ||
| it('์ ์ฅ๋์ด์๋ ์ด๊ธฐ ์ด๋ฒคํธ๊ฐ ์์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ๊ฒ ๋ถ๋ฌ์จ๋ค', async () => { | ||
| const createEvents: Event[] = [ |
There was a problem hiding this comment.
๋ฐ์ดํฐ๋ ๋ณ์๋ช ์ ๋ช ์ฌ๋ก ํ๋๊ฒ ์ข๋ค ์๊ฐํฉ๋๋ค!
There was a problem hiding this comment.
์ ๊ทธ๋ ๋ค์ ์ฝ๋ ๋ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค ๐
|
|
||
| // Date ๊ฐ์ฒด์ธ์ง ํ์ธ | ||
| expect(targetDateTime).toBeInstanceOf(Date); | ||
| expect(String(targetDateTime)).toBe('Invalid Date'); |
There was a problem hiding this comment.
์ ์ด๊ฑฐ ์ด๋ ๊ฒ ํ๋๊ฑฐ์๊ตฐ์. ์ ๊บผ์ ์ด์ํ๊ฒ ํด๋ฒ๋ ธ๋ค
There was a problem hiding this comment.
์ ๊ฐ ์ด์ํ๊ฒ ํ ๊ฒ์ผ์๋ ... ๐ฅน
Medium
7์ฃผ์ฐจ ๊ณผ์ ์ฒดํฌํฌ์ธํธ
๊ธฐ๋ณธ๊ณผ์
Medium
์ง๋ฌธ
React Notistack - https://notistack.com/
notistack์ด๋ผ๋ React ์๋ฆผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ ์คํธ ํ๊ฒฝ์์ ๊ฐ์์ผ๋ก ๋์์ํค๊ธฐ ์ํ ๋ชจํน ์ฝ๋์ ๋๋ค.
vi.fn()์ผ๋ก ์์ฑ๋ enqueueSnackbarFn์ ์ค์ ์๋ฆผ์ ํ๋ฉด์ ๋์ฐ์ง ์์ผ๋ฉด์๋ ํจ์ ํธ์ถ ์ฌ๋ถ, ํธ์ถ ํ์, ์ ๋ฌ๋ ๋ฉ์์ง ๋ฑ์ ์ถ์ ํ ์ ์๋ ํจ์์ ๋๋ค.
vi.mock์ ํตํด notistack ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ useSnackbar ํ ๋ง ๊ฐ์ง ํจ์๋ก ๊ต์ฒดํ๊ณ , ๋๋จธ์ง ๊ธฐ๋ฅ๋ค์ ์๋ณธ์ ๊ทธ๋๋ก ์ ์งํฉ๋๋ค. ์ดํ ํ ์คํธ ์งํ์ enqueueSnackbarFn๋ฅผ ์ฌ์ฉํ๋ฉด ํ ์คํธ ์คํ ์ค ์ค์ ํ์ ์ด ๋จ์ง ์์ ํ ์คํธ ์งํ์ ๋ฐฉํด๋ฐ์ง ์์ผ๋ฉด์๋, expect๋ฅผ ์ฌ์ฉํด ์๋ฆผ ๊ธฐ๋ฅ์ด ์ฌ๋ฐ๋ฅด๊ฒ ํธ์ถ๋์๋์ง ํ์ธ ๊ฐ๋ฅํฉ๋๋ค.
Provider ๋ํ์ ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ํ๊ฒฝ๊ณผ ๋์ผํ ์ปจํ ์คํธ๋ฅผ ํ ์คํธ์์ ์ ๊ณตํ๊ธฐ ์ํด ํ์ํฉ๋๋ค.
์ด๋ฌํ Provider๋ค ์์ด๋ ํ ์คํธ ์ค์ธ ์ปดํฌ๋ํธ๋ค์ด ํ์ํ ์ปจํ ์คํธ๋ฅผ ์ฐพ์ง ๋ชปํด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ์์๊ณผ ๋ค๋ฅด๊ฒ ๋์ํ ์ ์์ต๋๋ค.
๊ฐ ํจ์๋ ํ ์คํธ์ฉ Mock ์๋ฒ์์ CREAT,UPDATE,DELETE ๊ธฐ๋ฅ์ ๋ด๋นํฉ๋๋ค.
beforeEach์์ ์ด ์ค์ ๋ค์ ์ฌ์ฉํ์ฌ ๋ชจ๋ ํ ์คํธ๊ฐ ๋์ผํ ์กฐ๊ฑด์์ ์คํ๋๋๋ก ์ผ๊ด์ฑ์ ๋ณด์ฅํฉ๋๋ค.
์ฌํ ๊ณผ์
๊ณผ์ ์ ํํ๊ณ
๊ธฐ์ ์ ์ฑ์ฅ
ํ ์คํธ ์ฝ๋๋ฅผ ์ฒ์ ์ ํ๋๋ฐ ์ด์ ๋ง์ด ์นํด์ก์ต๋๋ค. ํนํ ๋น๋๊ธฐ/๋๊ธฐ ํ ์คํธ ๋ฐฉ์์ ์ฐจ์ด์ , API ์์ฒญ์ Mock ๋ฐ์ดํฐ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ๋ค์ํ ํ ์คํธ ๋ฉ์๋๋ค์ ์ฌ์ฉ๋ฒ๊ณผ ์ฐจ์ด์ ์ ์ดํดํ๊ฒ ๋์์ต๋๋ค.
toBe๋ ์ฐธ์กฐ ๋น๊ต์ ์์๊ฐ ๋น๊ต์ ์ฌ์ฉํ๊ณ , toEqual์ ๊ฐ์ฒด์ ๋ด๋ถ ๋ด์ฉ๊น์ง ๊น์ ๋น๊ต๋ฅผ ํ ๋ ์ฌ์ฉํ๋ค๋ ์ ์ ๋ฐฐ์ ์ต๋๋ค.
queryByTestId๋ ์์๊ฐ ์์์ง ์์์ง ๋ชจ๋ฅผ ๋ ์ฌ์ฉํ๋ฉฐ null์ ๋ฐํํ๊ณ , getByTestId๋ ๋ฐ๋์ ์กด์ฌํ ๊ฒ์ผ๋ก ์์๋๋ ์์์ ์ฌ์ฉํ๋ค๋ ์ฐจ์ด์ ๋ ์์๋์ต๋๋ค.
ํ ์คํธ ์ฝ๋ ์ฒซ ๋ง๋จ์ธ๋ฐ ๋๋ฌด ์ฌ๋ฐ๊ณ ์ด๋ ต๊ณ ์ ๊ธฐํ์ต๋๋ค. ์ ํํ ์ ๋์ฝ๐ฆ ๊ฐ์ ์กด์ฌ์๋๋ฐ ์ค์ ๋ก ๋ง๋์ ๋ฟ๋ ๋ง์ ธ๋ณด๊ณ ๋ง๋ ๊ฑธ์ด๋ณด๊ณ ์๊น์๋ฅผ ๊ด์ฐฐํด๋ณธ ๋๋์ด์์ต๋๋ค.
๊ด์ฐฐํด๋ณธ ํ๊ธฐ๋ผ๊ณ ํ๋ค๋ฉด ์์ง์ ์ฌ๋ฐ๊ณ ํฅ๋ฏธ์ง์งํ๋ฐ ์ฃผ๋ณ ์ฌ๋๋ค์ ๋ค๋ค ์ฌ๋ฏธ์์ดํด์ ๋ฉ์ฉ์ ๋๋์ ๋๋ค. ์ ๋ค๋ค ์ฌ๋ฏธ์๋์ง ์ ์ถํด๋ณด์๋ฉด ํ ์คํธ ์ฝ๋๋ ๊ธฐํ, UX์ ์ธ ์ธก๋ฉด์์ ๊ณ ๋ คํด์ผํ ๊ฒ์ด ๋ง๊ณ ๊ทธ ๋ถ๋ถ์ ์ฝ๋๋ก ํ์ด์ผ ํ๋ค๋ณด๋ UX์ ์นํ์ง ์๋ค๋ฉด ์ฝ๋๋ฅผ ์งค ๋๋ง๋ค ๊ณ ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฝ๋ ํ์ง
๋ ธ๋ ฅํ ๋ถ๋ถ
๋ฆฌํฉํ ๋ง์ ์งํํ๋ฉด์ ์์ํจ์์ด๊ฑฐ๋ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํ๊ณ ์งง์์๋ก, ๊ทธ๋ฆฌ๊ณ ์์ง๋๊ฐ ๋๊ณ ๊ฒฐํฉ๋๊ฐ ๋ฎ์ ์ฝ๋์ผ์๋ก ํ ์คํธ ์ฝ๋ ์์ฑ์ด ํจ์ฌ ์์ํ๋ค๋ ๊ฒ์ ์ฒด๊ฐํ์ต๋๋ค.
๋ฐ๋ฉด ํตํฉํ ์คํธ์ฒ๋ผ ๊ด๋ฆฌํด์ผ ํ ์ํ๊ฐ ๋ง์์ง๊ฑฐ๋ ๊ธฐ๋ฅ์ด ๋ณต์กํด์ง์๋ก ํ ์คํธ ์ฝ๋์ ๋ณต์ก๋๋ ํจ๊ป ์ฆ๊ฐํ๋ฉฐ, ๊ณ ๋ คํด์ผ ํ ๋ถ๋ถ์ด ๋ง์์ ธ ๋์น๋ ๋ถ๋ถ์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ๋ ๋์์ง๋ค๋ ์ ์ ๊นจ๋ฌ์์ต๋๋ค.
ํ ์คํธ ๋ชฉ ๋ฐ์ดํฐ ๊ด๋ฆฌ์ ๋ํด์๋ ๊ณ ๋ฏผํด๋ณด์์ต๋๋ค. ๋ณ๋์ dummies.ts ํ์ผ๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ ๊ณ ๋ฏผํ๋๋ฐ, ์ค๋ณต ์ฌ์ฉ๋๋ ๋ถ๋ถ์ด ํฌ๊ฒ ์๊ณ ๋ฐ์ดํฐ์์ด ๋ง์ง ์์์ ํ ํ์ผ ๋ด์์ ํ ์คํธ๋ณ๋ก ํ์ํ ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๋ ๊ฒ์ด ๊ฐ๋ ์ฑ ๋ฉด์์ ๋ ์ข๋ค๊ณ ํ๋จํ์ต๋๋ค.
์ค์ ๋ก handlerUtils.ts๋ด๋ถ์ ๋ชฉ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ์์ด ํ ์คํธ ์ฝ๋ ์์ฑ์ ๋งค๋ฒ ํด๋น ํ์ผ๋ก ์ด๋ํ์ฌ ๋ชฉ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๋ฉด์ ์งํํ์์ต๋๋ค.
ํ์ต ํจ๊ณผ ๋ถ์
๊ฐ์ฅ ํฐ ๋ฐฐ์์ TDD(Test-Driven Development)์ ์ค์์ฑ์ ๋๋ ๊ฒ ์ ๋๋ค. UI๋ฅผ ๊ธฐ์ค์ผ๋ก ๋์ค์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ๊ณ ๋ฏผ ํ ๊ฒ์ด ๋ง์ ๋๋ฌด ์ด๋ ค์ ๊ณ , ์์ฑ๋ ๊ธฐ๋ฅ์ ๋ํด ํ ์คํธ๋ฅผ ๋ง๋ค๋ค ๋ณด๋ ๋์น๋ ๋ถ๋ถ๋ค์ด ์๊ฒผ์ต๋๋ค.
ํ ์คํธ ์ฝ๋๋ฅผ ๋จผ์ ์์ฑํ๊ณ ๊ทธ์ ๋ง์ถฐ ๊ฐ๋ฐ์ ์งํํ๋ TDD ๋ฐฉ์์ด ํจ์ฌ ํจ์จ์ ์ผ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. ํนํ ์์ธํ UX ๊ธฐํ์๋ฅผ ๊ธฐ์ค์ผ๋ก ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ฉด ํจ์ฌ ์ฒด๊ณ์ ์ด๊ณ ์์ฑ๋ ๋์ ํ ์คํธ๊ฐ ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค.
๋ํ ๊ฐ๋ฐ์๋ค์ด ์ ํ ์คํธ ์ฝ๋ ์์ฑ์ ์ซ์ดํ๋์ง๋ ์ดํดํ๊ฒ ๋์์ต๋๋ค. ์ด์ ํ์ฌ์์ ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ฐ ํ ์คํธ ์ฝ๋์ ์ค์์ฑ์ ์๊ณ ํ๋ก ๋์ ํ์ผ๋, ํ๋ก๋ํธ ์ฝ๋๊ฐ ํด๋ฆฐํ์ง ์์ ํ ์คํธ ์ฝ๋๋ฅผ ๋ชจ๋ ํต๊ณผํ๋๋ฐ๋ ๋ถ๊ตฌํ๊ณ ํฌ๊ฒ ์๋ฌ๊ฐ ํฐ์ง ์ ์ด ์์์ต๋๋ค. ํ๋ก๋ํธ๋ฅผ ๋น ๋ฅด๊ฒ ๊ฐ๋ฐํ ํ์ ๋ง๋๋ ํ ์คํธ ์ฝ๋๋ ๋์ ์๋ฏธ๊ฐ ํฌ์๋ ์ ์์ผ๋ฉฐ, ์ด ํ ์คํธ ์ฝ๋๋ฅผ ์๋ฒฝ์ ๊ฐ๊น๊ฒ ๋ง๋ค๊ธฐ ์ํด์๋ ์๋นํ ์๊ฐ ํฌ์๊ฐ ํ์ํ๋ค๋ ๊ฒ์ ๊ณผ์ ํ๋ฉด์ ๋ ๋ค์ ๋๊ผ์ต๋๋ค.
๊ณผ์ ํผ๋๋ฐฑ
ํตํฉ ํ ์คํธ๊ฐ ๋จ์ ํ ์คํธ๋ณด๋ค ํจ์ฌ ์ด๋ ต๋ค๋ ๊ฒ์ ์ค๊ฐํ์ต๋๋ค. ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ์ํ๊ฐ ์ฝํ์๋ ์ํฉ์์ ๋ชจ๋ ์ผ์ด์ค๋ฅผ ๋ค ์ปค๋ฒํ๋ ค๋ค ๋ณด๋ ํ ์คํธ ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ , ์์ธ ์ฒ๋ฆฌ๊น์ง ์์ธํ๊ฒ ํ๋ ค๋ฉด ํ๋์ ๋ณด๊ธฐ ํ๋ค์ด์ง๋ค๋ ๋๋ ๋ง๊ฐ ์์์ต๋๋ค.
ํ ์คํธ ์ฝ๋๋ ํด๋ฆฐ ์ฝ๋๋งํผ์ด๋ ๊ฐ๋ ์ฑ์ด ์ค์ํ๊ณ ๊ฐ์ธ์ ์ทจํฅ์ ๋ง์ด ํ๋ ๊ฒ ๊ฐ์์, ํ ๋ด์์ ์ผ๊ด๋ ์คํ์ผ ๊ฐ์ด๋๋ ๋ฐฉํฅ์ฑ์ด ์๋ค๋ฉด ๋ ์ข์ ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ํนํ ํ ์คํธ ์ฝ๋๋ฅผ ์ฒ์ ์์ฑํ๋ ์ ์ฅ์์๋ ๋ช ํํ ๊ฐ์ด๋๋ผ์ธ์ด ์์์ผ๋ฉด ๋ ์ฒด๊ณ์ ์ผ๋ก ์ ๊ทผํ ์ ์์์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฆฌ๋ทฐ ๋ฐ๊ณ ์ถ์ ๋ด์ฉ
ํ ์คํธ ๋๋ฏธ๋ฐ์ดํฐ ๊ด๋ฆฌ ๊ณ ๋ฏผ
ํ์ฌ๋ ๊ฐ ํ ์คํธ ํ์ผ ๋ด์์ ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์๋๋ฐ, ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง ๋๋ฅผ ๋๋นํ ํจ๊ณผ์ ์ธ ํ ์คํธ ๋ฐ์ดํฐ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ด ์๋์ง ๊ถ๊ธํฉ๋๋ค. ์ธ์ ๋ถ๋ฆฌํ๊ณ ์ด๋ค ๊ธฐ์ค์ผ๋ก ๊ตฌ์กฐํํ๋ ๊ฒ์ด ์ข์๊น์?
์ด์ ๋ฉํ ๋ง๋ ์ฝ์น๋๊ป์ ์ค๋ฌด์์ ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ก ๋ถ๋ฆฌํด์ ์ฌ์ฉํ์๋ ๊ฒ์ ๋ณด์ฌ์ฃผ์ จ๋๋ฐ ๊ทธ ๋ฐฉ๋ฒ์ด ์ค์ ๋ก ๊ด์ฐฎ์ ๋ฐฉ๋ฒ์ด์ด์ ์ฑํ๋๋์ง ์๋๋ฉด ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ ์์๋๋ฐ ๊ทธ๋ ๊ฒ ๋ฐ๋๊ฒ ๋๊ฑด์ง๋ ๊ถ๊ธํฉ๋๋ค.
ํตํฉํ ์คํธ vs ๋จ์ํ ์คํธ ๋น์จ๊ณผ ์ ๋ต
ํตํฉํ ์คํธ๊ฐ ๋จ์ํ ์คํธ๋ณด๋ค ์์ฑํ๊ธฐ ์ด๋ ต๊ณ ๋ณต์กํ๋ค๋ ๊ฒ์ ๊ฒฝํํ์ต๋๋ค. ์ค์ ํ๋ก์ ํธ์์๋ ์ด ๋์ ์ ์ ํ ๋น์จ์ด๋ ์ฐ์ ์์๋ฅผ ์ด๋ป๊ฒ ์ ํ๋์ง, ๊ทธ๋ฆฌ๊ณ ํตํฉํ ์คํธ ์์ด ๋จ์ํ ์คํธ๋ง ์งํํ ๊ฒฝ์ฐ ํฌ๊ฒ ๋ฌธ์ ๊ฐ ์์๊น์?
ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ์ผ๋ถ ๋จ์ํ ์คํธ์ ๋ด์ฉ์ด ํตํฉํ ์คํธ์๋ ๋น์ทํ๊ฒ ์ฌ์ฉ๋์๋๋ฐ ๋จ์ํ ์คํธ์์ ์ต๋ํ ์ปค๋ฒํ๊ณ ํตํฉ ํ ์คํธ์์๋ ๋ฑ! ๋จ์ผ ui์ ์ธ ๋ถ๋ถ๋ง ํ ์คํธํ๋ฉด ๋์ง ์์๊น..ํ๊ณ ์์ํด๋ดค๋๋ฐ ๋ง๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค!