[Spring] TDD와 Unit Test

박이레·2022년 10월 16일
0

Spring

목록 보기
1/12

 테스트 코드는 매우 중요합니다. 또한 편리합니다. 테스트 코드를 작성하는 습관을 들이면 많은 이점이 있습니다. 먼저 TDD와 Unit Test에 대해 알아봅시다. 아래 그림을 Red Green Cycle이라고 합니다.



TDD(Test Driven Development)

TDD는 '테스트가 주도하는 개발'입니다. 개발 단계 중 테스트 코드를 가장 먼저 작성합니다.

①항상 실패하는 테스트를 먼저 작성합니다(Red)
②테스트가 통과하는 프로덕션 코드를 작성합니다(Green)
③테스트가 통과하면 프로덕션 코드를 리팩토링합니다(Refactor)

TDD 꼭 해야 하나요?

TDD는 책을 쓰는 과정과 비슷합니다.

책을 쓸 때는 ①목차를 구성하고 ②목차에 맞는 내용을 구성합니다. ③이후 초안을 고치는 작업을 반복합니다.

TDD는 ①테스트 코드를 작성하고 ②코드를 개발합니다. ③이후 코드를 수정하는 작업을 반복합니다.

글쓰기에서 퇴고는 매우 중요합니다. 인턴기자 시절 선배들은 일필휘지로 좋은 기사를 쓰는 줄 알았습니다. 그러나 그렇지 않았습니다. 좋은 글은 수많은 퇴고를 거쳐 탄생했습니다. 프로그래밍도 비슷합니다. 계속된 테스트와 수정을 통해 좋은 프로그램을 만들 수 있습니다.


Unit Test(단위 테스트)

Unit Test는 TDD의 첫 번째 단계인 기능 단위의 테스트 코드를 작성하는 것입니다. 순수하게 테스트 코드만 작성합니다.

Unit Test는 장점이 뭔가요?

① 개발단계 초기에 문제를 발견하게 도와줍니다.
② 리팩토링이나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인할 수 있습니다.
③ 기능에 대한 불확실성을 감소시킬 수 있습니다.
④ 시스템에 대한 실제 문서를 제공합니다. Unit Test 자체를 문서로 사용할 수 있습니다.
★시간을 줄일 수 있습니다.★

Unit Test를 처음 접했을 때 반감이 들었습니다. 테스트 코드를 작성하는 것이 시간을 잡아먹는다는 생각이 들었습니다. 그러나 그렇지 않았습니다. 기존 개발 방식과 Unit Test 개발 방식을 비교해볼까요?

기존 개발 방식

① 코드를 작성합니다.
② Tomcat을 실행합니다.
③ API Test Tool(ex. postman)으로 HTTP를 요청합니다.
④ 요청 결과를 System.out.println()으로 확인합니다.
⑤ 결과가 다르면 Tomcat을 중지하고 코드를 수정합니다.

아래 그림은 기존 개발 방식입니다.

코드를 수정할 때마다 이 과정을 반복해야 합니다. 아무리 컴퓨터 성능이 좋다고 해도 어플리케이션을 재시작하는 시간은 너무 지루합니다. 이 지루한 시간을 Unit Test가 해결할 수 있습니다.

Unit Test 개발 방식

① 테스트 코드를 작성합니다.
② 테스트 코드를 실행합니다.

테스트가 끝났습니다. 시간을 획기적으로 줄였고, 기능에 대한 안정성도 높였습니다. API Test Tool도 필요없습니다.

Unit Test 개발 방식을 사용하기 위해서는 단지 테스트를 진행하기 위한 어노테이션과 메소드 몇 개만 알아두면 됩니다.


Unit Test 사용 시에 알아두면 좋은 것

@RunWith(SpringRunner.class)
JUnit에 내장된 실행자 외에 다른 실행자(SpringRunner)를 실행합니다.
SpringBootTest와 JUnit 사이에 연결자 역할입니다.

WebMvcTest
선언할 경우 @Controller, @ControllerAdvice 등을 사용할 수 있습니다.
@Service, @Component, @Repository는 사용할 수 없습니다.

private MockMvc mvc
Web API를 테스트할 때 사용합니다.
GET, POST 등에 대한 API 테스트를 할 수 있습니다.
Spring MVC 테스트의 시작점입니다.

mvc.perform(get("/hello"))
MockMvc를 통해 /hello 주소로 GET 요청을 합니다.

.andExpect(status().isOk())
mvc.perform의 결과를 검증합니다.
HTTP status를 검증합니다.
위의 코드는 200(OK)인지 아닌지를 검증합니다.

.andExpect(content().string(hello))
mvc.perform의 결과를 검증합니다.
Response body의 내용을 검증합니다.
Controller에서 String "hello"를 리턴하기 때문에 이 값이 맞는지 검증합니다.


IntelliJ에서 Unit Test 작성 시 엉뚱한 것이 import되는 경우가 왕왕 있습니다. import를 주의해서 작성해야 합니다. 아래 코드를 참조하면 됩니다.


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void hello가_리턴된다() throws Exception {
        String hello = "hello";

        mvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string(hello));
    }
}


SpringBoot는 참 재밌습니다. JSP, Servlet를 작성하지 않았다면 이 재미를 몰랐을 겁니다. 문득 과거 기술에 고마움을 느낍니다.

💁‍♂️reference

스프링 부트와 AWS로 혼자 구현하는 웹 서비스

이동욱 지음ㅣ프리렉ㅣ2019ㅣ도서 정보

EOD.

profile
혜화동 사는 Architect

0개의 댓글