ํ
์คํธ ๊ณต๋ถ๋ ์๋ผ๊ฐ์๋์. ํ๊ต์์ ์ํจ๋ค๋ ์ด์ ๋๋ฌธ์ ๋งน๋ชฉ์ ์ผ๋ก ํ์ง๋ง๊ณ ์ฐ๋ฆฌ๊ฐ ์ง๊ธ ํ๊ณ ์๋๊ฒ ๋์ฒด ๋ฌด์์ธ์ง ์๊ฐํด๋ณด์๊ตฌ์.
ํ
์คํธ๋ฅผ ์งํํ๋ ์ด์ ๐ค
๊ฐ๋ฐ์๋ ์ฌ๋์ด๊ธฐ ๋๋ฌธ์ ์ค์๋ฅผ ํฉ๋๋ค. ํ
์คํธ๋ ์ด๋ฐ ์ค์๋ฅผ ๋ฐ๊ฒฌํ๊ณ ์ฝ๋๊ฐ ์๋ํ๋์ง ํ์ธํ๋๋ฐ ๋์์ด ๋ฉ๋๋ค. ๋ฌผ๋ก ์ฐ๋ฆฌ๋ค์ ํ๋ก์ ํธ์ฒ๋ผ ์์ ํ๋ก์ ํธ๋ฅผ ์ฒ์ ๊ฐ๋ฐํ ๋๋ ์ค์๊ฐ ์๋์ฌ ์๋ ์๊ฒ ์ง์. ํ์ง๋ง ๊ฐ๋ฐ์ ์๋ฃํ๊ณ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋งํ ๋๋ ์ด๋จ๊น์? (์ผ๋ง ์ ์ ์ ๊ฐ ์ ์ฒด์ ์ผ๋ก ๋ฆฌํฉํ ๋ง์ ํ์์ฃ .)
๋ฆฌํฉํ ๋ง์ ํ๊ฑฐ๋, ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ ๋์๋ ๊ธฐ์กด ๊ธฐ๋ฅ๊ณผ ์ฝ๋๋ค์ ๋ชจ๋ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํด์ผ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด๊ฒ์ ์ด๋ป๊ฒ ํ์ ํ ์ ์์๊น์? ํ๋ฉด์ ์ผ๋ก ์๋ฌด๋ฐ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ค๊ณ ์ ๋ง ์๋ฌด ๋ฌธ์ ๊ฐ ์๋๊ฒ ๋ง์๊น์? ๊ฐ๋ฐ์๊ฐ ๋ฐ๊ฒฌํ์ง ๋ชปํ ์๋ฌ๊ฐ ๋ฆด๋ฆฌ์ฆ ์ดํ์ ๋ฐ๊ฒฌ๋๋ฉด ์ด์ฉ์ฃ ? ์ฌ์ง์ด ๊ทธ ์๋ฌ๊ฐ ์๋ ์ ์๋ํ๋ ๊ธฐ๋ฅ์์ ๋ฐ๊ฒฌ๋์๋ค๋ฉด..? ์ด์ฉ๊ธด์. ํซํฝ์คํ๋๋ผ ์ธ๋ฉฐ ๊ฒจ์๋จน๊ธฐ๋ก ๋ฐค์ ์๊ฒ ์ฃ !
๊ฒฐ๊ตญ ํ
์คํธ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํ ๊ฒ์ด๊ธฐ๋ ํ์ง๋ง ๊ฐ๋ฐ์๋ฅผ ์ํ ๊ฒ์ด๊ธฐ๋ ํฉ๋๋ค. Lint
, Typescript
๋ฅผ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ๋งฅ๋ฝ์ด์ง์.
React(-Native) ์์ ํ
์คํธ๋ฅผ ํ๊ธฐ ์ ์..
์ฑ์ ํ
์คํธ ๊ฐ๋ฅ์ฑ์ ์ฌ๋ฆฌ๋ ค๋ฉด UI๋ UI ๋๋ก, ๋น์ฆ๋์ค ๋ก์ง์ ๋น์ฆ๋์ค ๋ก์ง๋๋ก ํ
์คํธ๋ฅผ ์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ปดํฌ๋ํธ์์ ๋น์ฆ๋์ค ๋ก์ง์ด๋ ๋ก์ง๋ค์ ๋ถ๋ฆฌํ๋ผ๋ ์๋ฏธ๊ฒ ์ง์!!
๋ ํ
์คํธ ๋ฐฉ๋ฒ๋ก ์ค์๋ ๋ง์ ๊ฒ๋ค์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ํํ ์๊ณ ์๋ TDD(ํ
์คํธ ์ฃผ๋ ๊ฐ๋ฐ๋ก, ์ค์ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ ์ ํ
์คํธ ์ฝ๋๋ฅผ ๋จผ์ ์์ฑํ๋ ๋ฐฉ๋ฒ๋ก )๋ ์ด๋ค ์ค ํ๋์ผ ๋ฟ์
๋๋ค. ๋จ์ง ์์ฆ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒ์ด๊ณ ์ฑ๋ฅ์ด ํ์คํ๋๊น ๋ง์ ๊ธฐ์
๋ค์์ TDD๋ฅผ ์ถ๊ตฌํ๋ ๊ฒ์ด ์๋๊น ์ถ์ต๋๋ค.
ํ๊ณ ์ถ์ ๋ง์ ์ฐ๋ฆฌ๊ฐ ๊ผญ ํ
์คํธ ์ฃผ๋ ๊ฐ๋ฐ์ ํ์ง ์์๋ ๋๋ค๋ ๊ฒ์ด๋๋๋ค. ์ค์ ๋ก ํ
์คํธ๊ฐ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ๋จผ์ ์์ฑํ๊ณ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ด ํ๋ฆฐ ๋ฐฉ๋ฒ์ด ์๋๋๋ค! ํ
์คํธ๋ฅผ ๋์ฒด ์ ํ๋์ง ๋ชธ์ ๊นจ๋ซ๊ณ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ต์ํด์ง ๋ TDD ๊ฐ์ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ด๋จ๊น์? ์ฐ๋ฆฐ ์์ง ํ
์คํธ ์ด๋ณด์์์~
@testing-library/react-native, Jest ๋ก ํ
์คํธํ๊ธฐ
ํ
์คํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์งง๊ณ ํ๊ฐ์ง๋ง ํ
์คํธํ๋ ๊ฒ์ด ์ด์์ ์
๋๋ค. it
ํจ์๋ ํ
์คํธ ํจ์์
๋๋ค. ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ๋ณผ๊น์.
it('given a date in the past, colorForDueDate() returns red', () => {
expect(colorForDueDate('2000-10-20').toBe('red'));
}
it given a date in the past, colorForDueDate() returns red ๊ฐ ํ๋์ ๋ฌธ์ฅ์ผ๋ก ์๋ฒฝํ ๊ฒ์ ๋์น์ฑ์
จ๋์. ์๋์ ๊ฐ์ ํค์๋๋ก ์ด๋ค ํ
์คํธ๋ฅผ ์ํํ๋์ง ๋ถ๋ช
ํ๊ฒ ํฉ์๋ค.
- given : ์ฌ์ ์กฐ๊ฑด
- when : ํ
์คํธ ์ค์ธ ํจ์์ ์ํด ์คํ๋๋ ํน์ ์ก์
- then : ์์๋๋ ๊ฒฐ๊ณผ
jest ์์ it
๊ณผ test
ํจ์๋ ์ด๋ฆ๋นผ๊ณ ๋ค ๋๊ฐ์์. ๋จ์ง ์ฒซ๋ฒ์งธ ์ธ์์ ํ๊ธ์ ์ฌ์ฉํ ๋์๋ it
๋ณด๋ค๋ test
๊ฐ ๋ ์ ์๋ฟ๋ ๊ฒ ๊ฐ์์.
๋จ์ ํ
์คํธ?
๋จ์ ํ
์คํธ๋ ๊ฐ๋ณ ํจ์๊ฐ์ ์ฝ๋์ ๊ฐ์ฅ ์์ ๋ถ๋ถ์ ํ
์คํธ ํฉ๋๋ค. ํ
์คํธ ์ค์ธ ๊ฐ์ฒด์ dependency ๊ฐ ์๋ค๋ฉด, mock ํจ์๋ฅผ ์์ฑํด์ผ ํ ์๋ ์์ด์. mock ํจ์๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ์ธ ๊ฐ์ง๋ก ์ค๋ช
ํ ์ ์์ด์.
- ํ
์คํธ๊ฐ ๋๋ฆฌ๊ณ ๋ถ์์ ํ ์ ์๋ค.
- ํด๋น dependency๊ฐ ํญ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ๋ค๊ณ ๋ณด์ฅํ ์ ์๋ค.
- ์๋ํํฐ ์๋น์ค๋ฅผ ํ์ฌ ์ฌ์ฉํ์ง ๋ชปํ๋ ์ํฉ์ผ ์ ์๋ค.
ํตํฉ ํ
์คํธ?
ํตํฉ ํ
์คํธ์์๋ ๊ฐ ๋จ์๋ค์ด ์ํธ ์์ฉํ๋ ๊ฒ์ ํ
์คํธํด์. ์ฆ, ๊ฐ ๊ฐ๋ฐ ๋จ์๋ค์ด ๊ฒฐํฉ๋๊ณ ํจ๊ป ํ
์คํธ๋์ด ์์๋๋ก ์๋ํ๋ ๊ฒ์ ํ์ธํ๋ ๊ฒ์ด์ง์.
์ปดํฌ๋ํธ ํ
์คํธ?
๋น์ฆ๋์ค ๋ก์ง์ ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง๊ฐ ๋๊ณ ์ ํํ๋๋ผ๋, ์ปดํฌ๋ํธ ํ
์คํธ๊ฐ ์๋ค๋ฉด ์ฌ์ฉ์์๊ฒ ์๋์ ๋ค๋ฅธ UI๋ฅผ ์ ๊ณตํ ์๋ ์์ด์. ์ปดํฌ๋ํธ ํ
์คํธ๋ ๋จ์ ํ
์คํธ์ ํตํฉ ํ
์คํธ์์ ์ฌ์ฉ๋ ์ ์์ด์. ์ฐ๋ฆฌ๋ ์ปดํฌ๋ํธ์ ์ด๋ค ๊ฒ์ ํ
์คํธํด์ผ ํ ๊น์?
- ์ํธ์์ฉ : ์ฌ์ฉ์์ ์ํธ ์์ฉํ ๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด (์๋ฅผ ๋ค๋ฉด ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ๋๋ ์ ๋!)
- ๋ ๋๋ง : ๋ฆฌ์กํธ์์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ ๋ ๋๋ง์ด ์ฌ๋ฐ๋ฅธ์ง ํ์ธํ๊ธฐ ์ํด (์๋ฅผ ๋ค๋ฉด UI์์ ๋ฒํผ์ ๋ชจ์ ๋ฐ ๋ฐฐ์น๊ฐ์ ๊ฒ!)
์๋ฅผ ๋ค๋ฉด onPress ๋ฆฌ์ค๋๊ฐ ์๋ ๋ฒํผ์ด ์์ ๋, ๋ฒํผ์ด ์ฌ๋ฐ๋ฅด๊ฒ ํ์๋๊ณ ๋ฒํผ์ ํด๋ฆญํ๋ ๊ฒ์ด ์ปดํฌ๋ํธ์์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋์ง ํ
์คํธํ๋ ๊ฒ์ด์ง์. ์๋ ์ฝ๋๋ฅผ ํ์ธํด๋ณผ๊น์.
function GroceryShoppingList() {
const [groceryItem, setGroceryItem] = useState('');
const [items, setItems] = useState([]);
const addNewItemToShoppingList = useCallback(() => {
setItems([groceryItem, ...items]);
setGroceryItem('');
}, [groceryItem, items]);
return (
<>
<TextInput
value={groceryItem}
placeholder="Enter grocery item"
onChangeText={(text) => setGroceryItem(text)}
/>
<Button
title="Add the item to list"
onPress={addNewItemToShoppingList}
/>
{items.map((item) => (
<Text key={item}>{item}</Text>
))}
</>
);
}
์ ์ฝ๋๋ ๊ฝค ์์ํ UI ์ปดํฌ๋ํธ๋ผ๊ณ ์๊ฐํด์. ๋ฌผ๋ก addNewItemToShoppingList
์ ๊ฐ์ ์ํ๊ด๋ฆฌ๋ฅผ ํ๋ ๋ก์ง์ด View์ ํผ์ฌ๋์ด ์์ง๋ง ์ด ์ ๋๋ ๋๋ถ๋ถ์ ์ํฉ์์ ํ์ฉํ ์ ์๋ ์์ค์ด๋ผ๊ณ ์๊ฐํด์.
์, ์๋ฌดํผ ์ฐ๋ฆฌ๋ ์ ์ฝ๋์์ ์ด๋ค ๊ฒ์ ํ
์คํธํด์ผ ํ ๊น์? props์ ์ด๋ค ๊ฒ๋ค์ด ๋ค์ด์ค๊ณ , state์ ๊ฐ์ด ๋ฌด์์ธ์ง ํ
์คํธํ์ง๋ง์ธ์! ์ด๋ ๋ฆฌํฉํ ๋ง์ผ๋ก ์ธํด ํ
์คํธ ์ฝ๋๊ฐ ์ฝ๊ฒ ๊นจ์ง ์ ์๊ณ ๋ค์ ์์ฑํด์ผํ ์ ์์ด์. ๊ฒฐ๋ก ์ UI๊ฐ ์ ๋ํ๋ฌ๊ณ , ๋ฒํผ์ ๋๋ ์ ๋ ์์๋๋ ๋์์ด ์ ๋๋์ง ํ
์คํธํ๋ฉด ๋ฉ๋๋ค!
test('given empty GroceryShoppingList, user can add an item to it', () => {
const { getByPlaceholder, getByText, getAllByText } = render(
<GroceryShoppingList />
);
fireEvent.changeText(
getByPlaceholder('Enter grocery item'),
'banana'
);
fireEvent.press(getByText('Add the item to list'));
const bananaElements = getAllByText('banana');
expect(bananaElements).toHaveLength(1); // expect 'banana' to be on the list
});
์ด ํ
์คํธ ์ฝ๋๋ <GroceryShoppingList/>
์ปดํฌ๋ํธ๊ฐ ์ฃผ์ด์ก์ ๋ ์ ์ ๊ฐ item
์ list
์ ์ถ๊ฐํ๋ ๊ฒ์ ํ
์คํธ ํฉ๋๋ค. ์ ํํ๊ฒ ํ๋์ ๊ธฐ๋ฅ์ ํ
์คํธ ํ๋ ๊ฒ์ด์ฃ . ์ด ์ผ๋ จ์ ๊ณผ์ ์ ํ
์คํธ ์ฝ๋๋ก ์์ฑํด๋ด
์๋ค.
๋จผ์ fireEvent
๋ jest์์ ์ ๊ณตํ๊ณ changeText()
๋ฅผ ์ด์ฉํ์ฌ ํด๋น ๋ถ๋ถ์ Text ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ ์ ๊ฐ input ์ ๋ฌด์ธ๊ฐ ์์ฑํ๋ค๊ณ ๊ฐ์ ํ๋ ๊ฒ์ด์ฃ . ๊ทธ ๋ค์ press()
๋ฅผ ์ด์ฉํ์ฌ Add the item to list
๋ผ๋ Text ๋ฅผ ๊ฐ์ง ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค. ๊ทธ ๋ค์ getAllByText('banana')
๋ก ๋ฐ๋๋๋ผ๋ ํ
์คํธ๋ฅผ ๊ฐ์ง ๋ชจ๋ ์๋ ๋ฉ์ธ ๋ฅผ ๊ฐ์ ธ์ต์๋ค. ๋ง์ฝ ์ด๊ฒ์ ๊ธธ์ด๊ฐ 1์ด๋ผ๋ฉด list
์ ์ ์ถ๊ฐํ๋ค๊ณ ์์ํ ์ ์์ด์.
๊ฒฐ๋ก
์ ์๊ฐ์๋ ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ํ
์คํธํ๋์ ๋ฐ๋ผ์ ์ฌ๋ฌ๊ฐ์ง ํ
์คํธ๋ฅผ ์ ์ฉํ ์ ์์ ๊ฑฐ ๊ฐ์์.
- components : ์ด ๋๋ ํ ๋ฆฌ์ ์กด์ฌํ๋ ์ปดํฌ๋ํธ๋ค์ ๋ชจ๋ View๋ฅผ ๋ด๋นํด์. ๋ฐ๋ผ์ ์ด ๋๋ ํ ๋ฆฌ๋ ์ปดํฌ๋ํธ ํ
์คํธ, ๋จ์ ํ
์คํธ, ํตํฉ ํ
์คํธ๋ฅผ ์ ์ฉํฉ์๋ค.
- screens : ์ด ๋๋ ํ ๋ฆฌ์ ์กด์ฌํ๋ ์ปดํฌ๋ํธ๋ค์ ๋ง์ ์ปดํฌ๋ํธ๋ค์ด ์ฌ์ฉ๋๋ ๊ณณ์ด๋, ์ปดํฌ๋ํธ ํ
์คํธ, ํตํฉ ํ
์คํธ๋ฅผ ์ ์ฉํ ์ ์์ ๊ฒ ๊ฐ์์.
- ๋น์ฆ๋์ค ๋ก์ง : ๋น์ฆ๋์ค ๋ก์ง๋ค์ ์ ๋ถ hooks๋ก ๋นผ์ ๋ฐ๋ก ๋จ์ ํ
์คํธํ๋ ๊ฒ ์ข์ ๊ฑฐ ๊ฐ์์.
๋ Jest ์์๋ ์ค๋
์ท ํ
์คํธ๋ฅผ ์ ๊ณตํด์. ๋ง๊ทธ๋๋ก ํ๋ฉด์ ์ฐ์ด์ ๊ฐ๋ฐ์๊ฐ ์ฝ์ ์ ์๋ ์ฝ๋๋ก ํ์ธํ ์ ์๋ ํํ๋ก ๋ณํํด์. ๋ง์ ๊ธ๋ค์์ ์ค๋
์ท ํ
์คํธ๋ฅผ ๊ถ์ฅํ์ง ์์์. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์์.
- View๊ฐ ๋ณ๊ฒฝ๋์ด fail ๋ ๊ฒ์ธ์ง, ๋ฒ๊ทธ๋ก ์ธํด fail ๋ ๊ฒ์ธ์ง ์ ์ ์๋ค.
- View๊ฐ ๋ณ๊ฒฝ๋๋ฉด jest --update-snapshots ๋ก ์๋ก์ด View ์ค๋
์ท์ ์
๋ฐ์ดํธ ํ ์ ์์ด์. ์ด๋ ์ค๋
์ท์ ์
๋ฐ์ดํธํ๋ฉด ์ธ์ ๋ ์ง ์ค๋
์ทํ
์คํธ๊ฐ ํต๊ณผ๋ ์ ์์์ ์๋ฏธํด์.
- ์ค๋
์ท์ ์ด๋ฏธ ๋ง๋ค์ด์ง UI ์ปดํฌ๋ํธ๋ฅผ ์ฐ๋ ๊ฒ์ด๋ผ TDD ๊ฐ์ ๋ฐฉ๋ฒ๋ก ์ ์ฌ์ฉํ ๋์ ์ค๋
์ท ํ
์คํธ๋ ๋ฌด์กฐ๊ฑด ์คํจํ ์ ๋ฐ์ ์์ด์.
- UI๋ ์ ์ ์ด์ง ์์์. ์์ฃผ ๋ณ๊ฒฝ๋๋ UI ๋ฅผ ๋ค๋ฃจ๋ ์ํฉ์์๋ ์ค๋
์ท ์
๋ฐ์ดํธ๋ฅผ ์์ฃผ ํ ํ
๊ณ ์ด๋ฐ ๋ฐฉ์์ ํ
์คํธ๋ ๋๋ฌด ํ์ ํ๊ฑฐ์ฃ .
Source
react-native official docs
์ค๋
์ท ํ
์คํธ์ ๋จ์