4. Testing Library
νμ΅ ν€μλ
Jest
Describe-Context-It ν¨ν΄
React Testing Library
Jest
π Jest 곡μλ¬Έμ
κ±°μ λͺ¨λ κ²μ κ°μΆ ν μ€ν λꡬ.
Mochaμ Chaiμ²λΌ RSpecμ describe-itμ μ§μνκ³ (describe-context-it), expectλ‘ λ¨μΈ(assertion)ν μ μλ€. Mockingλ λ€μν λ 벨μμ μ½κ² μ¬μ©ν μ μλ€.
BETTER SPECS β RSpec λ² μ€νΈ νλν°μ€ λͺ¨μ. κ·Έλλ‘ μΈ μλ μμ§λ§, μ°Έκ³ νμ.
Ginkgo - Go μΈμ΄ κ°λ°μλ₯Ό μν BDD ν μ€ν νλ μμν¬ (Go μΈμ΄ μ¬λ‘)
JUnit5λ‘ κ³μΈ΅ ꡬ쑰μ ν μ€νΈ μ½λ μμ±νκΈ° ****(Java μΈμ΄ μ¬λ‘)
Letβs RSpec β Jestλ RSpecμ let κ°μ κ±Έ μ§μνμ§ μκΈ° λλ¬Έμ, ν΅μ¬ μμ΄λμ΄λ₯Ό κ°μ Έμμ μ λΉν μμ€μμ μ μ¨μΌ νλ€.
κΈ°λ³Έμ μΈ ν
μ€νΈ μ½λ
ν μ€νΈ μ½λμ λ³νλ₯Ό κ³μ λ°μνλ €λ©΄,
npx jest --watchAll
ν μ€νΈλ₯Ό λ¨Όμ μ§κ³ ꡬνλΆλ₯Ό λ§λ λ€ -> TDD (Test Driven Development)
function add(x: number, y: number): number {
return x + y;
}
test('add', () => {
expect(add(1, 2)).toBe(3);
});
BDD μ€νμΌμ ν
μ€νΈ μ½λ
ννλ ₯μ΄ μ’μμ§κ³ , κ³ λ―Όν κΈ°νλ₯Ό μ 곡ν΄μ€λ€.
νλμ λ¬μ¬νλ€.
describe('add', () => {
it('returns sum of two numbers', () => {
expect(add(1, 2)).toBe(3);
});
});
context μ¬μ©νκΈ° (D-C-I Pattern)
const context = describe;
describe('add ν¨μλ', () => {
context('λ κ°μ μμκ° μ£Όμ΄μ‘μ λ', () => {
it('λ μ«μμ ν©μ λλ €μ€λ€.', () => {
expect(add(1, 2)).toBe(3);
});
});
});
npx jest --verbose
ν μ€νΈ μ½λμ μ€λͺ μ΄ μ‘°κΈ λ μμΈνκ² λμ¨λ€
React Testing Library
UI ν μ€νΈμ νΉνλ λΌμ΄λΈλ¬λ¦¬. κ±°μ E2E Test(PlayWright, Cypress)μ²λΌ μΈ μ μλ€.
λ¨, βF/E ν μ€νΈ = only React μ»΄ν¬λνΈ ν μ€νΈβκ° λλ μν©μ μ΅λν νΌνλ κ² μ’λ€. λ³Έμ§μ μ§μ€νμ§ λͺ»νκ³ λ무 λ§μ ν μ€νΈ μ½λλ₯Ό μμ±ν μνμ΄ μλ€. μ μ§λ³΄μλ₯Ό λκΈ° μν΄ ν μ€νΈ μ½λλ₯Ό μμ±νλλ°, ν μ€νΈ μ½λλ₯Ό μλͺ» μμ±νλ©΄ μ€νλ € μ μ§λ³΄μλ₯Ό μ ν΄ν μ μλ€.
μ°Έκ³ μμ:
κ°λ¨ν ν
μ€νΈ μ½λ
test('Greeting', () => {
render(<Greeting name="world" />);
screen.getByText('Hello, world!');
screen.getByText(/Hello/);
expect(sceen.queryByText(/Hi/)).not.toBeInTheDocument();
});
μ½λ©μ νκΈ° μ μ ν΄μΌ ν μΌ
μꡬμ¬νμ λͺ νν νλ κ²
λνκΈ°λ₯Ό λ§λ€ κ²μΈμ§, κ³±νκΈ°λ₯Ό λ§λ€ κ²μΈμ§
inputμΌλ‘λ μκ°μ λ°μ κ²μΈμ§, λΆμ λ°μ κ²μΈμ§
λͺ μΈλ₯Ό λͺ ννκ² νκΈ°
μμ λ₯Ό λ§λ λ€.
λ²κ·Έλ λͺ μΈμ μ νλλ‘ μλνμ§ μλ κ², λͺ μΈμ μ μλμ§ μμ κ²λ λ²κ·ΈλΌκ³ λ³Ό μ μλ€.
λ²κ·Έλ₯Ό μ‘κΈ° μ μΌ μ’μ μμ μ μ½λ©μ νκΈ° μ , λͺ μΈλ₯Ό λ³΄κ³ λΉ μ§ λΆλΆμ΄ μλμ§ νμΈ
λͺ μΈλ₯Ό λ°λΌ μ€κ³λ₯Ό νλ€.
μμ£Ό κ°λ¨ν μ¬λ¬ λ¨κ³λ‘ μͺΌκ°κΈ°
μ½λ©μ νλ©΄μ λ°°μ°κ² λλ€. μ€κ³κ° λ§μλμ§ νλ Έλμ§.
μ€κ³λ₯Ό κ°μ νκ² λλ€, κ°μ λ μ€κ³μ λ°λΌ λ€μ μ½λ©μ νλ€.
μ΄λ€ λ¬Έμ λ₯Ό ν΄κ²°νλ €κ³ νμλμ§ μꡬμ¬νμ λͺ ννκ² νλ κ²μ΄ κ°μ₯ μ€μνλ€. μꡬμ¬ν λͺ μΈλ₯Ό ν μ€νΈ μ½λλ‘ λ―Έλ¦¬ μμ±ν΄ λμΌλ©΄ ν μ€νΈ μ½λλ₯Ό ν΅κ³Όμν€κΈ°λ§ νλ©΄ λλ€. κ·Έλ¦¬κ³ κ°μ νλ€. 무μμ λ§λ€λ €κ³ νλμ§λ₯Ό μκ³ κ·Έκ²μ νμν κ²μ κ²°μ νκ³ μ΄λ£¨μ΄ μ§λλ‘ λ§λ€κΈ°. λ§λλ κ³Όμ μμ μ¬λ¬κ°μ§ νΌλλ°±μ μ»λλ€. μ¬κΈ°μ λ°°μ°λ κ²μ΄λ€. 무μμ΄ μλͺ»λμλμ§ μ°Ύμμ κ³ μΉλ©΄ λλ€. λμμμ΄ λ§λλ κ³Όμ μμμ λ°°μ°λ©΄ λλ€.
λ΄κ° ν μΌ μ¦λͺ
νκΈ°
λ΄κ° ν μΌμ λ¨μ΄ νκ² λ§λ€μ§ λ§μ. ν μ€νΈ μ½λλ₯Ό μμ±νμ. νλ§λ€ 컀λ²λ¦¬μ§μ κΈ°μ€μ λ€λ₯΄μ§λ§ ν μ€νΈ 컀λ²λ¦¬μ§ 100%λ₯Ό μ μ§νλ©΄ μ λ§ κ°λ ₯νλ€. λ΄ μΌμ λ΄κ° μλ£νμ.
Ginkgo - Go μΈμ΄ κ°λ°μλ₯Ό μν BDD ν
μ€ν
νλ μμν¬
Ginkgo: GoμΈμ΄μ© BDD ν μ€ν νλ μμν¬ BDDλ TDDμ ν κ°λλ€. TDDλ Test First μΌνΈλ°±μ μ€ν 3κ°λ‘ μ€λͺ νλ€ (Red, Green, Refactor) μ€ν¨νλ ν μ€νΈλ₯Ό λ§λλ κ²μ μ΄λ €μνλ€, λ μμ±ν΄μΌ ν μ§ λͺ¨λ₯΄κ² λ€. λ²κ·Έλ 무μμΈκ°?
1945λ 9μ 9μΌ κ·Έλ μ΄μ€ νΈνΌ(λ―Έκ΅μ μ»΄ν¨ν° κ³Όνμμ΄μ λ―Έκ΅ μμ¬μ μ΅μ΄μ μ¬μ± ν΄λ μ λ )κ° νλ²λλνκ΅μμ Mark2κ° μ€μλνλ κ²μ λ°κ²¬, μ»΄ν¨ν° νλ‘μ λλ°©μ΄ μμμ
μ¬λλ€μ λꡬλ μ€μλ₯Ό νλ€, μ΄λ»κ² νλ©΄ λ²κ·Έλ₯Ό μ€μΌ μ μμκΉ? κΈ°κ³μ΄λ‘ νλ‘κ·Έλλ°μ ν΄μ κ·Έλ λ€. μ¬λμ λ§μ²λΌ κ°λ°μ νλ©΄ μ΄λ¨κΉ. μ¬λμ μΈμ΄μ²λΌ λμ΄μλ κ²μ κΈ°κ³μ΄λ‘ λ°κΎΈλ κ², μ»΄νμΌλ¬ κ·Έλμ λμ¨ κ²μ΄ μ½λ³Ό(COBOL)μ΄λ€. μ½λ³Όμ μ΄λ¨Έλ.
μννΈμ¨μ΄μμ λ²κ·Έλ₯Ό μ€λͺ νλ λ§μ€μ νλλ₯Ό κΌ½μλ©΄ κΈ°λνμ§ μμ κ². κ²μμμ μ νλ₯Ό λλ λλ° μΊλ¦ν°κ° μμ΄νλ€λ©΄?
μ€ν, μ¬μμ λͺ νν νλκ² μννΈμ¨μ΄μμ λ§€μ° μ€μνλ€. μννΈμ¨μ΄κ° μ€ν, μ¬μμ λ§κ² λμνλμ§ νμΈνλ κ²μ΄ ν μ€νΈνλ κ².
ν μ€νΈ μ½λλ₯Ό μμ±νλ λ²μ μ°λ¦¬ μ¬μμ λ§λμ§ λ§μ§ μλμ§ μμ±νλ κ².
μ ν ν€λ₯Ό λλ₯΄λ©΄ μ νλ₯Ό ν΄μΌ νλ€.
κΈ°λ₯ λͺ©λ‘μ λ§λ€λ©΄μ μ΄κ²μ ꡬννλ©΄ λλ€. κΈ°λ₯μ΄λ μννΈμ¨μ΄κ° μ΄λ»κ² λμνλλ, νμ
Behavior First, νμλ₯Ό λ¨Όμ μμ±νλ©΄ λλ€. κ³μ°κΈ°μμ 1 λλ₯΄κ³ + λλ₯΄κ³ 2 λλ₯΄κ³ = λλ₯΄λ©΄ 3μ΄ λμ¨λ€, μ¬μμ 미리 μ μν΄ λλλ€. μ¬μ€μ TDDλ κ°λ€, TDDλΌκ³ νλ©΄ λλΆλΆμ μ¬λλ€μ μ λͺ¨λ₯Έλ€. ννμ λ°κΏμ μ΄ν΄λ₯Ό λλλ€.
Describe 'JUMP'
It should push the hero off the floor
It should put the hero in the air for 10 seconds
μ νλ λ¨μνλ°, μ΄λ€ κΈ°λ₯μ μν©μ λ°λΌ κ΅μ₯ν λ€λ₯΄κ² μλν μ μλ€.
Describe 'ATTACK'
Context 'without a weapon' It should do 1 point of damage
Context 'with a sword' it should do 10 points of damage
D-C-I ν¨ν΄μ μ΄μ©νμ¬ ν μ€νΈ μ½λλ₯Ό μμ±νκΈ° ν μ€νΈ μ½λμ μλκ° λμ± λͺ νν λλ¬λλ€.
describe 1κ°μ μ¬λ¬κ°μ context, κ·Έ μμ κ²°κ³Όλ₯Ό νννλ it
TDD on Spring ~ λ΄μλ TDD ~
TDD, λ²μνλ©΄ ν μ€νΈ μ£Όλ κ°λ° μΌνΈλ°± - TDD by Example, TDDμ μ ꡬμλ€. OOPμμμ patternμ μ μνλ€.
μ€μ λ‘ κ°λ°μ νλ©΄μ μ΄λ€ λ¬Έμ λ€μ΄ μμ λ ν΄κ²° λ°©λ²μ λͺ¨μλμ κ²μ΄ XP(μ΅μ€νΈλ¦Ό νλ‘κ·Έλλ°) λͺκ°μ§ Practicesλ€μ΄ λμ¨λ€.
Test First Programming, μ΄λ»κ² νλκ°? μΌλ¨ μ€ν¨λ₯Ό μν¨λ€. λ€μμ ν΄κ²°μ νλ€. κ·Έλ¦¬κ³ κ°μ μ νλ€.
κ°λ°μλ Problem Solving, λ¬Έμ λ₯Ό ν΄κ²°νλ€. μΌμ ν Goalμ΄ μλ€.
μ§μ§λ‘ ν΄λλ?
μ΄λ»κ² μ μ μλ?
μ΄λ»κ² νλ©΄ μ§μ§λ‘ νλμ§ μ μ μλ?
μ¦κ±°κ° μμ΄μΌ νλ€.
μ§μ§λ‘ λ€ νμ΄μ?
λ¬Έμ μλκ±°μ£ ?
ν루λ₯Ό μμ ν΄μ λ§λ€μ΄λΈ μ½λμ§λ§, λ¬Έμ κ° μμΌλ©΄ 100μΌ λμ μ½μ§μ νκ² λλ€. μ΄ν μμ μ νλλΌλ λμ€μ μ½μ§μ νμ§ μλλ€λ©΄ ν¨μ¬ λ«μ§ μμκΉ?
κ°λ°μ μ§ννκ³ μλΉμ€λ₯Ό λ°μΉνκΈ° μ μ νμΈν΄λ³΄λ λ²κ·Έκ° λ무 λ§λ€. μ°¨λΌλ¦¬ λ€μ λ§λλκ² λ λΉ λ₯Ό κ² κ°μ λ€μ λ§λ μ λ μλ€. μ΄λ° κ²μ κΈ°μ λΆμ±λΌκ³ νλ€.
λͺ©νλ₯Ό μ΄λ»κ² μΈμ°λ©΄ μ’λ? SMARTνκ² μΈμΈ κ².
Specific (ꡬ체μ )
Measurable (μΈ‘μ κ°λ₯)
Attainable (λ¬μ± κ°λ₯)
Realistic (νμ€μ )
Timely (κΈ°κ°)
λͺ©νλ₯Ό μ°κΈ°, μ΄ λͺ©νλ€μ μκ² λλ μ λͺ©λ‘μΌλ‘ λ§λ€κΈ°. κ·Έλ¦¬κ³ νλμ© μ€ννκΈ°(CHECK LIST)
λͺ©νλ, μ§κΈμ μλλ κ² -> μ€ν¨λ₯Ό μλ―Ένλ€. κΈ°λ₯Όμ°κ³ μ΄λ»κ² ν΄μλ λκ² ν΄μΌ νλ€. μΌλ¨ λκ² νλΌ.
μ무λ κ²κ° μλλΌ μ λλ‘ μλνλλ‘ νλ€. λ°©λ²μ΄ μλλΌ μ¬λ°λ₯Έ κ²°κ³Όκ° μ€μνλ€. ν΄κ²°μ΄ λ λ€μμλ κ·Έλλ‘ κΉλνκ² κ³ μ³λΌ. μλνκΈ° μν΄ λΉμ΄ν λ°©λ²μ μΌκΈ° λλ¬Έμ
κ°μ μ ν λ μ€μν κ²μ λ²κ·Έλ₯Ό λ§λ€μ΄ λ΄λ©΄ μλλ€. κ·Έλλ‘ κ°μ μ νλ κ² -> μ΄μ μ λ§λ€μλ ν μ€νΈλ₯Ό ν΅κ³Όνλ κ² μΈμ λ νμ μ λλ‘ μλνλλ‘ νλκ²μ΄ ν΅μ¬μ΄ λλ€.
ν μ€νΈ μ½λλ₯Ό λ¨Όμ μ§μΌ λ¬Έμ κ° μμκΈ΄λ€. κΈ°μ λΆμ±μ λν΄μλ λμν μ μλ€.
~ 08:24
Last updated