-
Notifications
You must be signed in to change notification settings - Fork 2
π ν μ€νΈμ½λμ λν μ°Έκ³ μλ£
λμ€μ λ°λ‘ μμΉ΄μ΄λΉ νκ² μ΅λλ€.
ν μ€νΈ with Jest: μ λ‘μ΄μκ² μ λλ‘ λ°°μ°κΈ° κ°μ | μ λ‘μ΄(μ‘°νμ) - μΈνλ°
2μκ°μΌλ‘ λλ΄λ νλ‘ νΈμλ ν μ€νΈ κΈ°λ³ΈκΈ° κ°μ | κ°λ³μ§ - μΈνλ°
- μκ°ν΄λ³΄λ Cypressλ μμλ€μ. λΉκ·Όμ μ΄κ±°μ΄λ€λλ°
κ·Όλ³Έμλ νλ‘ νΈμλ μ λν μ€νΈ κ°μ | μ΄μ©μ½λ© - μΈνλ°
- κ°μΈμ μΌλ‘ λ§μ½ TDD νλ‘μ νΈλ‘ κ°λ©΄ μ΄ λ°μ΄λΈ μ± μ λλ μ½μ΄λ΄μΌ ν κ² κ°μμ, μ΄κ±Έλ‘ κ·Έλ£Ήνλ‘μ νΈ λ΄λΆ μ€ν°λν΄λ μ¬λ°μ κ² κ°μ΅λλ€.
νλ‘ νΈμλ κ°λ°μκ° μμμΌ ν βμ λ ν μ€νΈβ μμ±λ² | μμ¦IT
νλ‘ νΈμλμμ μλ―Έμλ ν μ€νΈ μ½λ μμ±νκΈ°
νλ‘ νΈμλ ν μ€νΈ μ½λ λμ κΈ°
λͺ¨λ νλ‘ νΈμλ ν μ€νΈ μ λ΅βββ1νΈ
λͺ¨λ νλ‘ νΈμλ ν μ€νΈ μ λ΅βββ2νΈ
νλ°νΈμλ κ°λ°μ μν ν μ€νΈ μ λ¬Έ - μμ€24
μ€μ©μ μΈ νλ‘ νΈμλ ν μ€νΈ μ λ΅ (1) : NHN Cloud Meetup
μ€μ©μ μΈ νλ‘ νΈμλ ν μ€νΈ μ λ΅ (2)
[A5] νλ‘ νΈμλμμ TDDκ° κ°λ₯νλ€λ κ²μ 보μ¬λ립λλ€.
μμ±νλ €κ³ λ Έλ ₯νλ μ¬λλ μκ³ , μμ μνλ μ¬λλ μλ€.
λ무 νλ€κ³ , μΌμ μ μΉμ΄κ³ λ°λΉ μ λμ€μ.. λμ€μ νλ€λ³΄λ©΄..
λμ€μ κ²°μ½ μ€μ§ μμμ κ·Έλ λ€.
μΌνΈλ²‘μ΄λΌλ μ¬λμ΄ ν μ€νΈ μ£Όλ κ°λ°μ μ μ 리νλ€.
κΆκ·Ήμ λͺ©νλ Clean code
λΌκ³ λ§νλ κΉλν μ½λλ₯Ό λ§νλ€.
Test First programmingμ λ§νλ€.
- λ³΄ν΅ μ΄λ°
Red,
Green
,Refactor
λΌλ μΈμ΄ν΄μ λλ€. - ν μ€νΈλ₯Ό ν΅κ³Όμν€κ³ , μ€λ³΅μ μ κ±°νλ©΄μ κ°λ°μ μ§ννλ μ¬μ΄ν΄μΈλ°.. μ΄κ²λ§ 보면 μ½κ² μ κ·Όν μ μμ κ² κ°μλ°.. λ§μ μ¬λλ€μ΄ TDDμ λμ νκ³ λ§μ΄ μ’μ νλ€.
- μ°μ¬μλΆλ μ§κΈ μ’μ νλ€.
- μ½λ μ체κ°
Testable
νμ§ μμμ κ·Έλ λ€. -
Testable
ν μ½λλ₯Ό μμ±νμ§ μμμ κ·Έλ λ€. - μ°λ¦¬κ° μ μ§λ³΄μνλ μλΉμ€λ λ κ±°μκ° μ»€μ
Testable
νκΈ° μ½μ§ μλ€.
- κ΄μ¬μ¬μ λΆλ¦¬(Separation of concerns)
- μμ μ΄ κ΄μ¬κ°κ³ μλ λΆλΆμλ§ κ΄μ¬κ°μ Έμ κ°λ°νλ λ°©μμ λ§νλ€.
- μλνλ ν μ€νΈμ μ€ν
- μ μΌ λ¨Όμ ν μ€νΈ μ½λ μμ± (App componentλ₯Ό λ°νμλ‘ μκ²γ )
import React from 'react';
import {render} from '@testing-library/react';
import App from './App';
describe('App', () => {
it('redners tasks', () => {
const {container} = render({
<App />
});
expect(container).toHaveTextContent('μ무 μΌλ νκΈ° μ«λ€.');
});
});
- μ΄λ° ν μ€νΈ μ½λλ₯Ό μμ±νλ€.
- μ΄κ±Έ λΉ λ₯΄κ² ν΅κ³Όμν€κΈ° μν΄μ μλ¨ λ°©λ²μ κ°λ¦¬μ§λ§λΌ. μ΄κ² μμΉμ΄λ€.
import React from 'react';
export default function App() {
return (
<div>
<h1>To-do</h1>
<ul>
<li>
μ무μΌλ νκΈ° μ«λ€.
</li>
</ul>
</div>
);
}
- μ΄κ² μ°λ¦¬κ° μνλ λͺ¨μ΅μ μλλ€.
- κ΄μ¬μ¬μ λΆλ¦¬λ₯Ό μν΄μ μ°λ¦¬κ° μνλ ννλ‘ λΆλ¦¬νλ€.
List.test.jsx
λ₯Ό λ§λ λ€.
import {render} from '@testing-library/react';
import List from './App';
describe('List', () => {
it('redners tasks', () => {
const {container} = render({
<List />
});
expect(container).toHaveTextContent('μ무 μΌλ νκΈ° μ«λ€.');
});
});
List.jsx
λ₯Ό λ§λ λ€.
import React from 'react';
export default function App() {
return (
<ul>
<li>
μ무μΌλ νκΈ° μ«λ€.
</li>
</ul>
);
}
μ΄ν μ€νμ νλ©΄ ν μ€νΈκ° ν΅κ³Όκ° λλ€.
κ·Έλ°λ°, μ΄ λΆλΆμ΄ ν μ€νΈκ° μλλ€. μ°λ¦¬λ λ°°μ΄μ λ°μμ κ·Έ λ°°μ΄μ μλ Todo μ λͺ©λ€μ 보μ¬μ£Όλ €κ³ νλ κ²μ΄λ€.
import {render} from '@testing-library/react';
import List from './App';
describe('List', () => {
it('redners tasks', () => {
const tasks = [{id:1, title: 'μ무 μΌλ νκΈ° μ«λ€.'}]
const {container} = render({
<List tasks={tasks}/>
});
expect(container).toHaveTextContent('μ무 μΌλ νκΈ° μ«λ€.');
});
});
import React from 'react';
export default function App({tasks}) {
return (
<ul>
{tasks.map((task)=>{
<li key={task.id}>
{task.title}
</li>
})}
</ul>
);
}
μ΄λ κ² λ°κΏμ£Όλ©΄ λμμ νλ€.
μ¬κΈ°κΉμ§λ μ΄μ§ λΆμνλ€. ν μ€νΈκ° μ λλ‘ λμνλ μ§ μ μ μλ€.
import {render} from '@testing-library/react';
import List from './App';
describe('List', () => {
it('redners tasks', () => {
const tasks = [{id:1, title: 'μ무 μΌλ νκΈ° μ«λ€.'}, {id:2, title: '건물 맀μ
'}]
const {container} = render({
<List tasks={tasks}/>
});
expect(container).toHaveTextContent('μ무 μΌλ νκΈ° μ«λ€.');
expect(container).toHaveTextContent('건물 맀μ
');
});
});
μ΄λ κ² νλ©΄ ν
μ€νΈλ₯Ό ν΅κ³Όνλ€. List
λ ν
μ€νΈλ₯Ό μ ν΅κ³Όνκ³ μλ€.
λ€μ App
μ μμ ν΄λ³΄μ.
import React from 'react';
import List from './List';
export default function App() {
return (
<div>
<h1>To-do</h1>
<List />
</ul>
</div>
);
}
κ·Έλ κ² νλ©΄ ν μ€νΈκ° κΉ¨μ§λ€.
κ° ν
μ€νΈλ λ
립μ μΈλ°, App
λ΄μ List
λ μνλ₯Ό λ°κΎΈμ§ μκ³ μκΈ° λλ¬Έμ΄λ€. κ·Έλμ μμλ‘ λ°κΎΈμ§ μν₯λ©΄ ν
μ€νΈκ° κΉ¨μ§κ² λμ΄μλ€.
import React from 'react';
import List from './List';
export default function App() {
const tasks = [{id:1, title: 'μ무 μΌλ νκΈ° μ«λ€.'}, {id:2, title: '건물 맀μ
'}]
return (
<div>
<h1>To-do</h1>
<List tasks={tasks}/>
</ul>
</div>
);
}
μμλ‘ μνλ₯Ό λ§λ€μ΄μ λ£μ΄μ£Όλ©΄, ν μ€ν¬λ ν΅κ³Όλλ€.
ν μ€νΈμ, μλνλ ν μ€νΈ μ½λλ₯Ό λ³΄κ³ λΈλΌμ°μ λ₯Ό λ³Ό νμλ κ±°μ μλ€.
κ±°μ νμ€ν νΌλλ°± 루νκ° μκ³ , κ±°μ νμ€ν νΌλλ°± λͺ¨λκ° μκΈ° λλ¬Έμ΄λ€.
-
μ μ°λκ°?
-
μνκ΄λ¦¬ μΈ‘λ©΄μμ μ΄λ€.
-
μ’ λ κΉκ² λ€μ΄κ°μ 보μ.
-
Reactμ κ΄μ¬μ¬ λλ¬Έμ μ΄λ€.
-
Reactμ κ΄μ¬μ¬λ state reflection μ¦, μν λ°μμ΄λ€.
-
μνκ° μ λ¬λλ©΄ μνλ₯Ό λ°μνλ κ²μ μ κ²½μ΄λ€.
-
κ·Έλμ 리μ‘νΈλ μν κ΄λ¦¬μ λν΄μλ κ΄μ¬μ΄ μλ€. λ°μμλ§ κ΄μ¬μ΄ μμ λΏμ΄μ§.
-
λ‘κ·ΈμΈ κΈ°λ₯ λ±μ΄ μΆκ°λκ³ μ±μ΄ λΉλν΄μ§λ©΄, κ΄μ¬μ¬ λΆλ¦¬κ° μ΄λ ΅κ³ ν μ€νΈνκΈ° μ΄λ €μ΄κ±Έ μμ£Ό νμΈν μ μλ€.
Container componentλ§ reduxμ μ‘΄μ¬λ₯Ό μκ³ μλ§ μνλ₯Ό κ°μ Έμ¨λ€.
κ·Έ μνλ₯Ό κ°μ Έμμ presentation componentμ μ λ¬νλ€.
μ~ κ·Έκ±° λ΄ κ΄μ¬μ¬ μλμΌ.
κ·Έλμ μμμ μ»΄ν¬λνΈλ₯Ό μκ² μκ² λ§λ€ μ μλλ‘ μ£Όμλ₯Ό κΈ°μΈμ¬μΌ νλ€.
μμ‘΄μ±μ΄ μκΈ°μ§ μκ³ λ λ€μ ν μ€νΈλ₯Ό μ½κ² μμ±ν μ μκ³ , κ·ΈλμΌ TDDλ₯Ό ν μ μλ€.