Spring Test

DB에 μ ‘κ·Όν•˜λŠ” μ½”λ“œλ₯Ό ν…ŒμŠ€νŠΈν•˜κ³  싢을 λ•ŒλŠ” μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ?

λ‹¨μˆœν•˜κ²Œ μ„œλ²„λ₯Ό μ‹€ν–‰μ‹œν‚€κ³ , μ‹€μ œ 데이터λ₯Ό μž…λ ₯ν•΄λ³Ό 수 μžˆλ‹€. ν•˜μ§€λ§Œ 맀번 이 μž‘μ—…μ„ ν•˜λŠ” 것은 μƒλ‹Ήνžˆ 번거둜운 일이닀. ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό ν™œμš©ν•΄λ³΄μž.

ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” src/test 에 μžˆμœΌλ―€λ‘œ, src/test μ—μ„œμ˜ application.properties νŒŒμΌμ„ μ„€μ •ν•΄μ•Ό ν•œλ‹€. κ·ΈλŸ¬λ―€λ‘œ 이 μ•ˆμ—μ„œ DB urlμ΄λ‚˜ username λ“± 섀정을 ν•΄μ•Ό ν•œλ‹€.

spring.datasource.url=
spring.datasource.username=

ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ³΄μž.

@SpringBootTest // @SpringBootApplication을 μ°Ύμ•„μ„œ μ„€μ •μœΌλ‘œ μ‚¬μš©ν•œλ‹€.
class RepositoryTest {
    @Autowired
    ItemRepository itemRepository;
    
    @Test
    void save() {
        //given
        Item item = new Item("itemA", 10000, 10);

        //when
        Item savedItem = itemRepository.save(item);

        //then
        Item findItem = itemRepository.findById(item.getId()).get();
        assertThat(findItem).isEqualTo(savedItem);
    }
}

μœ„μ™€ 같은 μ„€μ •μ˜ ν…ŒμŠ€νŠΈλŠ” 문제점이 μ‘΄μž¬ν•œλ‹€. μ‹€μ œ μ‹€ν–‰ν•  μ„œλ²„μ˜ λ°μ΄ν„°λ² μ΄μŠ€μ™€ ν…ŒμŠ€νŠΈμ˜ λ°μ΄ν„°λ² μ΄μŠ€κ°€ λ™μΌν•˜λ‹€. λ”°λΌμ„œ 이전에 μ„œλ²„λ₯Ό μ‹€ν–‰ν•˜λ©΄μ„œ μ €μž₯된 데이터듀이 λ³΄κ΄€λ˜μ–΄ μžˆλ‹€. 즉, λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό λΆ„λ¦¬μ‹œμΌœμ•Ό ν•œλ‹€.

λ°μ΄ν„°λ² μ΄μŠ€ 뢄리

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ ν…ŒμŠ€νŠΈ ν™˜κ²½κ³Ό μ‹€μ œ ν™˜κ²½μ„ λΆ„λ¦¬μ‹œμΌœμ•Ό ν•œλ‹€. 이 λ•Œ λ– μ˜¬λ¦΄ 수 μžˆλŠ” κ°€μž₯ κ°„λ‹¨ν•œ 방법은 ν…ŒμŠ€νŠΈ μ „μš© DBκ°€ 있으면 λœλ‹€. 즉 μƒˆλ‘œμš΄ ν…ŒμŠ€νŠΈ μ „μš© DBλ₯Ό λ§Œλ“€κ³  ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” 이 DBλ₯Ό ν†΅ν•΄μ„œ μ‹€ν–‰ν•˜λ„λ‘ ν•˜λ©΄ λœλ‹€.

이 λ•Œ ν…ŒμŠ€νŠΈ λ°μ΄ν„°λ² μ΄μŠ€μ—λ„ ν…ŒμŠ€νŠΈν•  ν…Œμ΄λΈ”μ„ 생성해야 ν•œλ‹€. 그리고 src/test/application.properties λ₯Ό ν…ŒμŠ€νŠΈ ν™˜κ²½μ— 맞게 λ‹€μ‹œ μ„€μ •ν•œλ‹€.

μ΄λ ‡κ²Œ ν•œ 후에 ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ™„λ²½ν• κΉŒ? ν…ŒμŠ€νŠΈλ₯Ό μ—¬λŸ¬ 개 ν•΄μ•Όλ˜λŠ” 상황을 λ– μ˜¬λ €λ³΄μž. save() ν…ŒμŠ€νŠΈκ°€ μ‹€ν–‰λ˜λ©΄ μ½”λ“œ λ‚΄μ˜ μ‚½μž…λœ Item은 κ·ΈλŒ€λ‘œ μ‘΄μž¬ν•  것이닀. 이 λ•Œ λ‹€λ₯Έ ν…ŒμŠ€νŠΈκ°€ μžˆλ‹€λ©΄, 이 ν…ŒμŠ€νŠΈμ— save() μ—μ„œ μƒμ„±λœ Item은 이 ν…ŒμŠ€νŠΈμ— 영ν–₯을 주게 λœλ‹€.

λ§Œμ•½μ— μœ λ‹ˆν¬ 킀에 ν•΄λ‹Ήν•˜λŠ” 데이터가 μ‚½μž…λ˜μ§€ μ•ŠλŠ” 것을 ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈκ°€ μžˆλ‹€κ³  ν•΄λ³΄μž.

이 μ½”λ“œλŠ” λ§ˆμ§€λ§‰ λ‘œμ§μ—μ„œ μ‚½μž…μ΄ μ•ˆλ˜λŠ”μ§€ ν™•μΈν•œλ‹€. 그런데 λ§Œμ•½ save() μ—μ„œ ItemA와 같은 μœ λ‹ˆν¬ν‚€λ₯Ό κ°€μ§€λŠ” 데이터가 이미 μ‚½μž…λ˜μ—ˆλ‹€λ©΄, ItemA μ‚½μž… λ‹¨κ²Œμ—μ„œ 였λ₯˜κ°€ λ°œμƒν•œλ‹€. 결과적으둜 μ•žμ„œ μ‹€ν–‰λœ ν…ŒμŠ€νŠΈλ‘œ 인해 ν•΄λ‹Ή ν…ŒμŠ€νŠΈκ°€ 영ν–₯을 λ°›μ•˜λ‹€. 이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” 각각의 ν…ŒμŠ€νŠΈλŠ” λ…λ¦½μ μœΌλ‘œ λ™μž‘ν•΄μ•Ό ν•œλ‹€.

ν…ŒμŠ€νŠΈμ— μžˆμ–΄μ„œ μ€‘μš”ν•œ 원칙이 μžˆλ‹€.

  • ν…ŒμŠ€νŠΈλŠ” λ‹€λ₯Έ ν…ŒμŠ€νŠΈμ™€ 격리해야 ν•œλ‹€.

  • ν…ŒμŠ€νŠΈλŠ” λ°˜λ³΅ν•΄μ„œ μ‹€ν–‰ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ ν…ŒμŠ€νŠΈκ°€ 끝날 λ•Œλ§ˆλ‹€ μΆ”κ°€λœ 데이터에 DELETE SQL 문을 μ‚¬μš©ν•˜λŠ” 것도 방법이 될 수 μžˆμ§€λ§Œ, 이 방법이 쒋은 해결책일 것 κ°™μ§€λŠ” μ•Šλ‹€. λ§Œμ•½ 쀑간에 μ‹€νŒ¨ν•œλ‹€λ©΄, DELETE SQL 을 ν˜ΈμΆœν•˜μ§€ λͺ»ν•  μˆ˜λ„ μžˆλ‹€.

λ‘€λ°±

νŠΈλžœμž­μ…˜μ— λŒ€ν•΄μ„œ μƒκ°ν•΄λ³΄μž. νŠΈλžœμž­μ…˜μ€ 컀밋과 둀백이 μ‘΄μž¬ν–ˆλ‹€. μš°λ¦¬λŠ” 둀백을 μ΄μš©ν•œλ‹€.

ν…ŒμŠ€νŠΈκ°€ λλ‚˜κ³  νŠΈλžœμž­μ…˜μ„ λ‘€λ°±ν•œλ‹€λ©΄ λ°μ΄ν„°λŠ” μ œκ±°λœλ‹€. 쀑간에 μ‹€νŒ¨ν–ˆλ‹€ν•˜λ”λΌλ„, νŠΈλžœμž­μ…˜μ„ μ»€λ°‹ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— DB에 ν•΄λ‹Ή λ°μ΄ν„°λŠ” λ°˜μ˜λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ 각각의 ν…ŒμŠ€νŠΈλ₯Ό νŠΈλžœμž­μ…˜ λ‹¨μœ„λ‘œ μƒκ°ν•˜κ³ , ν•΄λ‹Ή ν…ŒμŠ€νŠΈ μ’…λ£Œ μ „ 둀백을 μˆ˜ν–‰ν•œλ‹€.

각 ν…ŒμŠ€νŠΈμ— μ μš©ν•˜κΈ° μœ„ν•΄ @BeforeEach, @AfterEach λ₯Ό μ‚¬μš©ν•œλ‹€.

transactionManager λŠ” PlatformTransactionManager λ₯Ό μ£Όμž…λ°›μ•„μ„œ μ‚¬μš©ν•œλ‹€. μŠ€ν”„λ§ λΆ€νŠΈλŠ” μžλ™μœΌλ‘œ μ μ ˆν•œ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό μŠ€ν”„λ§ 빈으둜 λ“±λ‘ν•œλ‹€. @BeforeEach λ₯Ό 톡해 각각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μ‹€ν–‰ 전에 νŠΈλžœμž­μ…˜μ„ μ‹€ν–‰ν•œλ‹€. @AfterEach λ₯Ό 톡해 ν…Œμ΄νŠΈ μΌ€μ΄μŠ€ μ™„λ£Œ ν›„ νŠΈλžœμž­μ…˜μ„ λ‘€λ°±ν•œλ‹€.

@Transactionnal

μœ„μ—μ„œ μš°λ¦¬λŠ” @BeforeEach , @AfterEach λ₯Ό μ‚¬μš©ν–ˆλ‹€. 이 κ³Όμ •λ§ˆμ €λ„ μŠ€ν”„λ§μ€ @Transactional μ• λ…Έν…Œμ΄μ…˜ ν•˜λ‚˜λ‘œ κΉ”λ”ν•˜κ²Œ ν•΄κ²°ν•  수 μžˆλ‹€.

μŠ€ν”„λ§μ΄ μ œκ³΅ν•˜λŠ” @Transactional μ• λ…Έν…Œμ΄μ…˜μ€ 주둜 μš°λ¦¬κ°€ μ„œλΉ„μŠ€μ—μ„œ μ‚¬μš©ν•˜λ©΄ 둜직이 μ„±κ³΅μ μœΌλ‘œ μˆ˜ν–‰ μ‹œ μ»€λ°‹ν•œλ‹€. 그런데 이 μ• λ…Έν…Œμ΄μ…˜μ„ ν…ŒμŠ€νŠΈμ—μ„œ μ‚¬μš©ν•˜λ©΄ μŠ€ν”„λ§μ€ νŠΈλžœμž­μ…˜μ„ μ‹€ν–‰ν•˜κ³  ν…ŒμŠ€νŠΈκ°€ λλ‚˜λ©΄ νŠΈλžœμž­μ…˜μ„ μžλ™μœΌλ‘œ λ‘€λ°±μ‹œν‚¨λ‹€. μ΄λ•Œ μ• λ…Έν…Œμ΄μ…˜μ€ λ©”μ„œλ“œμ— 뢙여도 λœλ‹€.

μž„λ² λ””λ“œ λͺ¨λ“œ DB

μœ„ 상황을 μ‚΄νŽ΄λ³΄λ©΄ ν…ŒμŠ€νŠΈμš© DBλŠ” λ§Œλ“€κ³  λ°”λ‘œ μ§€μ›Œμ§€λ―€λ‘œ DB λ‚΄ λ°μ΄ν„°λŠ” μ§€μ†λ˜μ§€ μ•ŠλŠ”λ‹€. λ‹¨μˆœνžˆ ν…ŒμŠ€νŠΈ κ²€μ¦μš©λ„μ΄κΈ° λ•Œλ¬Έμ— λͺ¨λ‘ μ‚­μ œν•΄λ„ 상관이 μ—†λ‹€.

λͺ‡λͺ‡ λ°μ΄ν„°λ² μ΄μŠ€λŠ” μž„λ² λ””λ“œ λͺ¨λ“œλ₯Ό μ œκ³΅ν•œλ‹€. μž„λ² λ””λ“œ λͺ¨λ“œλŠ” DBλ₯Ό μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— λ‚΄μž₯ν•΄μ„œ ν•¨κ»˜ μ‹€ν–‰ν•œλ‹€κ³  보면 λœλ‹€. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ’…λ£Œλ˜λ©΄ μž„λ² λ””λ“œ λͺ¨λ“œλ‘œ λ™μž‘ν•˜λŠ” λ°μ΄ν„°λ² μ΄μŠ€λ„ ν•¨κ»˜ μ’…λ£Œλ˜κ³ , 데이터도 λͺ¨λ‘ 사라진닀.

src/test/application.properties μ—μ„œ λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Όν•˜λŠ” μ„€μ • 정보λ₯Ό μ—†μ• κ³  μ‹€ν–‰μ‹œν‚€λ©΄, μŠ€ν”„λ§ λΆ€νŠΈλŠ” μž„λ² λ””λ“œ λͺ¨λ“œλ‘œ μ ‘κ·Όν•˜λŠ” DataSource λ₯Ό λ§Œλ“€μ–΄μ„œ μ œκ³΅ν•œλ‹€.

이 λ•Œ μž„λ² λ””λ“œ λͺ¨λ“œλ₯Ό μ‚¬μš©ν•˜λ©΄, ITEM ν…Œμ΄λΈ”μ— λŒ€ν•΄μ„œ λͺ¨λ₯΄κ³  μžˆλŠ” μƒνƒœκ°€ λœλ‹€. ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜κΈ°μ „ ν…Œμ΄λΈ” 생성 SQL을 날렀도 λ˜μ§€λ§Œ μŠ€ν”„λ§ λΆ€νŠΈλŠ” 이에 λŒ€ν•œ κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.

src/test 에 schema.sql 을 λ§Œλ“€κ³  ν…Œμ΄λΈ” 생성 SQL을 μž‘μ„±ν•œλ‹€.

이둜써 μš°λ¦¬λŠ” ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄ μ„œλ²„λ₯Ό 직접 μ‹€ν–‰μ‹œμΌœ ν™•μΈν•˜μ§€ μ•Šμ•„λ„ λœλ‹€. 그리고 μ‹€μ œ μ„œλ²„ DB와 ν…ŒμŠ€νŠΈ DBλ₯Ό λΆ„λ¦¬ν•˜μ˜€κΈ° λ•Œλ¬Έμ— μ„œλ‘œμ—κ²Œ 영ν–₯을 μ£Όμ§€ μ•Šκ³ , 둀백을 톡해 ν…ŒμŠ€νŠΈκ°„μ—λ„ μ„œλ‘œ 영ν–₯을 μ£Όμ§€ μ•ŠλŠ”λ‹€.

κ²°κ΅­ ν…ŒμŠ€νŠΈλŠ” λ‹€λ₯Έ ν…ŒμŠ€νŠΈμ™€ κ²©λ¦¬λ˜μ–΄ 있고, λ°˜λ³΅ν•΄μ„œ μ‹€ν–‰ν•  수 있게 λ˜μ—ˆλ‹€.

TDD(Test-Driven-Development)

TDDλŠ” λ™μž‘ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜κΈ° 전에 ν…ŒμŠ€νŠΈλ₯Ό λ¨Όμ € μž‘μ„±ν•˜κ³ , κ·Έ ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•¨μœΌλ‘œμ¨ ν…ŒμŠ€νŠΈλœ λ™μž‘ν•˜λŠ” μ½”λ“œλ₯Ό κ°œλ°œν•˜λŠ” 방법이닀.

TDDλŠ” μ„Έ κ°€μ§€ 단계가 ν•œ μ‚¬μ΄ν΄λ‘œ 이루어진닀.

  • ν…ŒμŠ€νŠΈ μž‘μ„±(λΉ¨κ°„ 뢈)

  • μ‹€ν–‰ κ°€λŠ₯ν•˜κ²Œ μ½”λ“œ μž‘μ„±(초둝 뢈)

  • λ¦¬νŒ©ν† λ§

λ¨Όμ € 컴파일쑰차 λ˜μ§€ μ•ŠλŠ” μ½”λ“œλ₯Ό λŒ€μƒμœΌλ‘œ λ¨Όμ € ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•œλ‹€. κ·Έ λ‹€μŒ ν…ŒμŠ€νŠΈ μ½”λ“œκ°€ 컴파일되고 μ‹€ν–‰κΉŒμ§€ λ˜λ„λ‘ μ½”λ“œλ₯Ό μž‘μ„±ν•œ ν›„, ν…ŒμŠ€νŠΈκ°€ ν†΅κ³Όλ˜λ©΄ ν…ŒμŠ€νŠΈμ˜ λ³΄ν˜Έμ•„λž˜ μ½”λ“œλ₯Ό λ‹€λ“¬λŠ”λ‹€.

예λ₯Ό λ“€μ–΄ 계산기에 λŒ€ν•œ ν…ŒμŠ€νŠΈλ₯Ό ν•œλ‹€κ³  κ°€μ •ν•΄λ³΄μž. 아직 Calculator 객체와 λ©”μ„œλ“œλ„ μž‘μ„±ν•˜μ§€ μ•Šμ•˜λ‹€. 이 λ•Œ μš°λ¦¬λŠ” μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 객체둜 인해 컴파일쑰차 λ˜μ§€ μ•Šλ”λΌλ„ λ¨Όμ € μž‘μ„±ν•˜κ³  μ»΄νŒŒμΌλΆ€ν„° 도도둝 μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ‚˜κ°„λ‹€. 즉, λ¨Όμ € ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰μ‹œμΌ°μ„ λ•Œ λΉ¨κ°„ 뢈이 λ‚˜μ˜€λ„λ‘ μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€.

κ·Έ λ‹€μŒ μœ„μ˜ 과정을 톡해 λŒμ•„κ°€λŠ” μ½”λ“œκΉŒμ§€ μž‘μ„±ν–ˆλ‹€λ©΄, 이제 ν•΄κ²°ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€. 이 λ•Œ κ°€λŠ₯ν•œ λΉ λ₯΄κ²Œ ν…ŒμŠ€νŠΈκ°€ ν†΅κ³Όν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€. 이 λ•Œ μ—¬κΈ°μ„œ β€˜λΉ λ₯΄κ²Œβ€™λΌλŠ” 말은 μ„±λŠ₯적으둜 λΉ λ₯΄κ²ŒλΌλŠ” 뜻이 μ•„λ‹ˆλΌ, μ΄ˆλ‘λΆˆμ„ λ„μš°λŠ” μ½”λ“œλ₯Ό 빨리 μž‘μ„±ν•˜λΌλŠ” λœ»μ΄λ‹€.

μœ„ μ½”λ“œμ—μ„œ Sample 클래슀λ₯Ό μƒμ„±ν•˜κ³  myState의 λ°˜ν™˜κ°’μ΄ true인지 ν™•μΈν•œλ‹€. 이 λ•Œ, Sample클래슀λ₯Ό μ •μ˜ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ 컴파일쑰차 λ˜μ§€ μ•Šμ„ 것이닀. λ”°λΌμ„œ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜λ©΄ λΉ¨κ°„λΆˆλ‘œ λ‚˜μ˜€κ²Œ λœλ‹€.

그러면 이제 이 ν…ŒμŠ€νŠΈλ₯Ό 돌리기 μœ„ν•΄μ„œ Sample 클래슀λ₯Ό 생성해야 ν•œλ‹€.

이제 ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” 컴파일될 것이닀. ν…ŒμŠ€νŠΈ λ©”μ„œλ“œλŠ” μ‹€ν–‰λ˜μ§€λ§Œ μ‹€νŒ¨ν•˜κ²Œ λœλ‹€. λ³΄λ‹€μ‹œν”Ό myStateλŠ” falseλ₯Ό λ°˜ν™˜ν•˜λŠ”λ°, ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œλŠ” trueκ°€ κΈ°λŒ€κ°’μœΌλ‘œ μ„€μ •λ˜μ–΄μžˆλ‹€. 이 λ•Œ TDD에 맞좰 μ΅œλŒ€ν•œ 빨리 λΉ¨κ°„λΆˆμ„ 초둝뢈둜 λ§Œλ“€λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ?

정말 λ‹¨μˆœν•˜κ²Œ μƒκ°ν•˜λ©΄ λ°˜ν™˜κ°’μ„ true둜 λ§Œλ“€λ©΄ λœλ‹€.

이제 ν…ŒμŠ€νŠΈκ°€ μ„±κ³΅ν•˜κ²Œ λ˜μ–΄ μ΄ˆλ‘λΆˆμ„ λ„μš°κ²Œ λœλ‹€. TDD의 λ‘λ²ˆμ§Έ λ‹¨κ³„κΉŒμ§€ μ™„λ£Œν•˜κ²Œ 된 μ…ˆμ΄λ‹€. 이제 λ¦¬νŒ©ν† λ§μ„ ν•΄λ³΄μž. 이 κ³Όμ •μ—μ„œ ν…ŒμŠ€νŠΈμ— μžˆλŠ” 데이터와 μ½”λ“œμ— μžˆλŠ” λ°μ΄ν„°μ˜ 쀑볡을 μ œκ±°ν•΄μ•Όν•œλ‹€.

ν…ŒμŠ€νŠΈ μ½”λ“œμ—λ„ trueκ°€ μ‘΄μž¬ν•˜κ³ , Sample 클래슀의 myStateμ—μ„œλ„ trueκ°€ μ‘΄μž¬ν•œλ‹€. κ²°κ΅­ μ€‘λ³΅μœΌλ‘œ trueκ°€ λ“±μž₯ν•˜κ³  μžˆλ‹€. 이λ₯Ό λ¦¬νŒ©ν† λ§ ν•΄λ³΄μž.

이λ₯Ό 톡해 myState λŠ” ν•˜λ“œ μ½”λ”©λœ 값이 μ•„λ‹ˆλΌ 객체 λ‚΄λΆ€μ˜ μƒνƒœλ₯Ό λ°˜ν™˜ν•˜κ²Œ λœλ‹€. 그리고 μƒμ„±μžμ˜ νŒŒλΌλ―Έν„° 이름을 μ•Œλ§žκ²Œ λ³€κ²½ν•˜μ˜€λ‹€.

ν•˜λ‚˜μ˜ 클래슀λ₯Ό μ •μ˜ν•΄κ°€λŠ” κ³Όμ •μ—μ„œ 컴파일이 λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 μ•Œλ©΄μ„œλ„ μ‹€ν–‰ν•˜κ³ , 컴파일만 될 뿐 ν…ŒμŠ€νŠΈλŠ” λ‹Ήμ—°νžˆ μ‹€νŒ¨ν•œλ‹€λŠ” 것을 μ•Œμ§€λ§Œ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν–ˆλ‹€. 사싀 λ‹Ήμ—°ν•œ 과정이라 μ§€λ£¨ν•˜κ³  κ·Έλƒ₯ κ±΄λ„ˆλ›°μ–΄λ„ 될 것 κ°™λ‹€λŠ” 생각이 λ“ λ‹€. κ²Œλ‹€κ°€ μ˜ˆμ‹œμ˜ μ½”λ“œλŠ” μƒλ‹Ήνžˆ λ‹¨μˆœν•œ 클래슀라 TDDκ°€ κ·Έλ‹₯ ν•„μš”ν•˜μ§€ μ•Šλ‹€κ³  λŠκ»΄μ§„λ‹€.

ν•˜μ§€λ§Œ 지루함 μ†μ—λŠ” λ‚΄κ°€ μƒκ°ν•œλŒ€λ‘œ μ½”λ“œκ°€ λ™μž‘ν•œλ‹€λŠ” 확신을 얻을 수 μžˆλ‹€. myState λ©”μ„œλ“œλŠ” μƒμ„±μžλ‘œ 건넀쀀 μƒνƒœλ₯Ό λ°˜ν™˜ν•œλ‹€. 이 μ½”λ“œμ˜ μ˜ˆμ‹œλŠ” μƒλ‹Ήνžˆ λ‹¨μˆœν•˜μ§€λ§Œ, μ½”λ“œκ°€ κΈΈμ–΄μ‘Œμ„ λ•Œ 둜직 상 λ¬Έμ œκ°€ λ°œμƒν•΄μ„œ 돌렀보고 값을 넣어보고 둜그λ₯Ό μ°μ–΄λ³΄λŠ” 상황이 λ§Žλ‹€. 이 λ•Œ TDD에 λŒ€ν•΄ μ •μ˜ν•œ μΌ„νŠΈλ°±μ€ μ½”λ“œ 변경에 λŒ€ν•œ 두렀움을 지루함을 λ°”κΎΈλŠ” 과정이라 λ§ν•œλ‹€.

μ˜ˆμ‹œ μƒν™©μ²˜λŸΌ 이런 μ½”λ“œλ„ μž‘μ€ λ‹¨κ³„λ‘œ μ„ΈλΆ„ν™”ν•  ν•„μš”λŠ” μ—†μ§€λ§Œ, ν•„μš”ν•œ 경우 μž‘μ€ λ‹¨κ³„λ‘œ λ‚˜λˆ„μ–΄ μ§„ν–‰ν•  쀄 μ•Œμ•„μ•Ό ν•œλ‹€.

λ¬Όλ‘  μ–Έμ œλ‚˜ TDDλ₯Ό ν†΅ν•œ 개발이 μ–Έμ œλ‚˜ 쒋은 것은 μ•„λ‹ˆλ‹€. TDD ν”Œλ‘œμš°λ₯Ό ν†΅ν•œ κ°œλ°œμ€ 그만큼 ν…ŒμŠ€νŠΈμ˜ λ¦¬μ†ŒμŠ€κ°€ μ†Œλͺ¨λœλ‹€. μ£Όμ–΄μ§„ 기간이 짧은데, TDD ν”Œλ‘œμš°λ₯Ό μ μš©ν•˜μ—¬ κ°œλ°œν•œλ‹€λŠ” 것은 λ°”λžŒμ§ν•˜μ§€ μ•Šλ‹€. κ²°κ΅­ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” λΉ„μš©κ³Ό μˆ˜μž‘μ—…μœΌλ‘œ ν…ŒμŠ€νŠΈν•˜λŠ” λΉ„μš©μ„ 비ꡐ해야 ν•œλ‹€. μœ„μ˜ Sample ν΄λž˜μŠ€λŠ” 사싀 λ°”λ‘œ Sample ν΄λž˜μŠ€μ— λŒ€ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ‚˜κ°€λŠ” 것이 훨씬 νš¨μœ¨μ μ΄λ‹€. 크게 λ³΅μž‘ν•˜μ§€ μ•Šκ±°λ‚˜ μ†Œκ·œλͺ¨ ν”„λ‘œμ νŠΈμ—μ„œ ν…ŒμŠ€νŠΈκ°€ μ—†κΈ° λ•Œλ¬Έμ— 퀄리티가 λ–¨μ–΄μ§€κΈ°λŠ” μ‰½μ§€μ•Šλ‹€.

μˆœμˆ˜ν•˜κ²Œ κ°œλ°œμ΄λΌλŠ” κ΄€μ μ—μ„œ TDDλŠ” μΆ©λΆ„νžˆ 쒋은 λ°©λ²•μ΄μ§€λ§Œ, λͺ¨λ“  것을 κ³ λ €ν•œ μ‹€μ œ μƒν™©μ—μ„œλŠ” μ‰½κ²Œ λ„μž…ν•˜κΈ°λŠ” μ–΄λ ΅λ‹€κ³  μƒκ°ν•œλ‹€.


μ°Έκ³ 

https://tech.kakaopay.com/post/implementing-tdd-in-practical-applications/

https://www.inflearn.com/course/μŠ€ν”„λ§-db-2/dashboard

Last updated