🌏 WEB/JAVA

Test-Driven-Development ν…ŒμŠ€νŠΈ 주도 개발

μ• μ •μ“° 2022. 3. 24. 00:54

TDD 개발 방식

TDD λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•œ 뒀에 μ‹€μ œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 것이닀.

ν…ŒμŠ€νŠΈκ°€ ν†΅κ³Όλœ μ½”λ“œλ§Œμ„ μ‹€μ œ μ½”λ“œλ‘œ μž‘μ„±ν•œλ‹€ -> 버그가 쀄고 μ†ŒμŠ€κ°€ 간결해지며 섀계가 κ°œμ„ λœλ‹€.

 

 - 섀계 λ‹¨κ³„μ—μ„œ ν”„λ‘œκ·Έλž˜λ° λͺ©μ μ„ 미리 μ •μ˜ν•œλ‹€.

 - 무엇을 ν…ŒμŠ€νŠΈν•΄μ•Ό 할지 미리 μ •μ˜ν•œλ‹€.

 - ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„± 도쀑 λ°œμƒν•˜λŠ” μ˜ˆμ™Έ 사항을 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— μΆ”κ°€ν•œλ‹€. (섀계 κ°œμ„ )

 

 

TDD ν”„λ‘œμ„ΈμŠ€

μ‹€νŒ¨ν•˜λŠ” μž‘μ€ λ‹¨μœ„ ν…ŒμŠ€νŠΈ μΆ”κ°€ -> ν…ŒμŠ€νŠΈ 톡과, μ΅œμ†Œν•œμ˜ μ½”λ”© -> κ΅¬ν˜„ 섀계 κ°œμ„ , 쀑볡 제거, λ¦¬νŒ©ν† λ§ , ν…ŒμŠ€νŠΈ 톡과 μœ μ§€

 

 

쒋은 ν…ŒμŠ€νŠΈμ˜ νŠΉμ§•

 

  • Fast: ν…ŒμŠ€νŠΈλŠ” λΉ λ₯΄κ²Œ λ™μž‘ν•˜μ—¬ 자주 돌릴 수 μžˆμ–΄μ•Ό ν•œλ‹€.
  • Independent: 각각의 ν…ŒμŠ€νŠΈλŠ” 독립적이며 μ„œλ‘œ μ˜μ‘΄ν•΄μ„œλŠ” μ•ˆλœλ‹€.
  • Repeatable: μ–΄λŠ ν™˜κ²½μ—μ„œλ„ 반볡 κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€.
  • Self-Validating: ν…ŒμŠ€νŠΈλŠ” 성곡 λ˜λŠ” μ‹€νŒ¨λ‘œ bool κ°’μœΌλ‘œ κ²°κ³Όλ₯Ό λ‚΄μ–΄ 자체적으둜 κ²€μ¦λ˜μ–΄μ•Ό ν•œλ‹€.
  • Timely: ν…ŒμŠ€νŠΈλŠ” μ μ‹œμ— 즉, ν…ŒμŠ€νŠΈν•˜λ €λŠ” μ‹€μ œ μ½”λ“œλ₯Ό κ΅¬ν˜„ν•˜κΈ° 직전에 κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.

 

 

Springμ—μ„œμ˜ TDD ν”„λ‘œκ·Έλž˜λ° 방법 

  • Repository -> Service -> Controller μˆœμ„œλ‘œ κ°œλ°œμ„ μ§„ν–‰ν•œλ‹€.
  • Repository κ³„μΈ΅μ˜ ν…ŒμŠ€νŠΈλŠ” H2와 같은 인메λͺ¨λ¦¬ λ°μ΄ν„°λ² μ΄μŠ€ 기반의 톡합 ν…ŒμŠ€νŠΈλ‘œ μ§„ν–‰ν•œλ‹€.
  • Service κ³„μΈ΅μ˜ ν…ŒμŠ€νŠΈλŠ” Mockitoλ₯Ό μ‚¬μš©ν•΄ Repository 계측을 Mockν•˜μ—¬ μ§„ν–‰ν•œλ‹€.
  • Controller κ³„μΈ΅μ˜ ν…ŒμŠ€νŠΈλŠ” SpringTest의 MockMvcλ₯Ό μ‚¬μš©ν•΄ μ§„ν–‰ν•œλ‹€.

 

 

μ°Έκ³  (μ™„μ „ μ’‹λ‹€ 정리 짱짱 γ…œγ…œ πŸ₯°)

https://mangkyu.tistory.com/143

 

[TDD] λ‹¨μœ„ ν…ŒμŠ€νŠΈ(Unit Test) μž‘μ„±μ˜ ν•„μš”μ„± (1/3)

1. λ‹¨μœ„ ν…ŒμŠ€νŠΈ vs 톡합 ν…ŒμŠ€νŠΈ 차이 [ λ‹¨μœ„ ν…ŒμŠ€νŠΈ(Unit Test) ] λ‹¨μœ„ ν…ŒμŠ€νŠΈ(Unit Test)λŠ” ν•˜λ‚˜μ˜ λͺ¨λ“ˆμ„ κΈ°μ€€μœΌλ‘œ λ…λ¦½μ μœΌλ‘œ μ§„ν–‰λ˜λŠ” κ°€μž₯ μž‘μ€ λ‹¨μœ„μ˜ ν…ŒμŠ€νŠΈμ΄λ‹€. μ—¬κΈ°μ„œ λͺ¨λ“ˆμ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—

mangkyu.tistory.com

 

 

상황에 λ”°λ₯Έ 예제 

 

1. μ›ν•˜λŠ” Item 을 찾을 λ•Œ 결과값이 μ‘΄μž¬ν•˜μ§€ μ•Šμ„ λ•Œ Exception 이 μ•„λ‹Œ null (List일 경우 빈 λ°°μ—΄)을 λ°˜ν™˜ν•œλ‹€.

  @DisplayName("μƒν’ˆ μ‘°νšŒμ‹œ μƒν’ˆμ΄ μ—†μ„λ•Œ μƒνƒœμ½”λ“œ 200을 λ°˜ν™˜ν•œλ‹€.")
  @Test
  void getEmptyItem() throws Exception {
  
    //given
    String name = "신라면";

    //when
    final ResultActions actions = mvc.perform(
        get("/item").param("name",name)
            .contentType(MediaType.ALL_VALUE)
            .accept(MediaType.APPLICATION_JSON)).andDo(print());

    //then
    actions.andExpect(status().isOk());

  }

 

2. μΆ”μƒν΄λž˜μŠ€ ν…ŒμŠ€νŠΈν•˜κΈ°

상항 : Mapstruct λ₯Ό μ‚¬μš©ν•˜κ³  μžˆλŠ”λ° 좔상 클래슀둜 λ³€κ²½ν•˜μ—¬ μ‚¬μš©ν•˜κ³  μžˆμ–΄ Mapper ν…ŒμŠ€νŠΈ ν•  λ•Œ 

	//when
    ItemMapper itemMapper = mock(ItemMapper.class, CALLS_REAL_METHODS);
    when(itemMapper.toDetailDto(item)).thenReturn(itemDetailDto);
    ItemDetailDto result = buyRequestMapper.toDetailDto(item);

 

λ°˜μ‘ν˜•