꾸준히 기록하자
[Spring] 단위 테스트(Unit Test)와 테스트 주도 개발(TDD)의 중요성 본문
728x90
아래 내용은 망나니개발자님의 블로그 내용을 공부하며 작성한 정리글입니다.
https://mangkyu.tistory.com/182
단위 테스트(Unit Test)를 작성해야 하는 이유
- 코드를 수정하거나 기능을 추가할 때 수시로 빠르게 검증할 수 있다.
- 리팩토링 시에 안정성을 확보할 수 있다.
- 개발 및 테스팅에 대한 시간과 비용을 절감할 수 있다.
비용이 크다라는 말은 통합 테스트를 위해 캐시, 데이터베이스 등 외부 컴포넌트들과 연결 등 시간이 필요하기 때문이다.
좋은 테스트의 특징
- Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
- Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
- Repeatable: 어느 환경에서도 반복 가능해야 한다.
- Self-Validating: 테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증되어야 한다.
- Timely: 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.
빠르게 독립적으로 어느 환경에서든 실행, 검증할 수 있어야 하고 테스트 코드는 실제 코드를 구현하기 직전에 구현한다.
테스트 코드를 먼저 작성해야 한 이유
- 깔끔한 코드를 작성할 수 있다.
- 장기적으로 개발 비용을 절감할 수 있다.
- 개발이 끝나면 테스트 코드를 작성하는 것은 매우 귀찮다. 실패 케이스면 더욱 그렇다.
처음 작성할 때에는 귀찮고 개발을 느리게 한다는 느낌을 받을 수 있지만, 장기적으로 보면 반드시 개발 비용을 아껴줄 것이다.
프로덕션 코드를 먼저 작성하였다면 이후에 테스트 코드를 작성하는 과정은 너무 귀찮다.
실패 테스트부터 작성해야 한다. 순차적으로 실패하는 테스트를 먼저 작성하고, 오직 테스트가 실패할 경우에만 새로운 코드를 작성해야 한다. 중복된 코드가 있으면 제거한다.
프로덕션 코드란: 프로그램 구현을 담당하는 부분으로 사용자가 실제로 사용하는 코드
테스트 주도 개발(TDD) 방법 및 순서
- 실패하는 작은 단위 테스트를 작성한다. 처음에는 컴파일 조차 되지 않을 수 있다.
- 빨리 테스트를 통과하기 위해 프로덕션 코드를 작성한다. 이를 위해 정답이 아닌 가짜 구현 등을 작성할 수도 있다.
- 그다음의 테스트 코드를 작성한다. 실패 테스트가 없을 경우에만 성공 테스트를 작성한다.
- 새로운 테스트를 통과하기 위해 프로덕션 코드를 추가 또는 수정한다.
- 1 ~ 4단계를 반복하여 실패/성공의 모든 테스트 케이스를 작성한다.
- 개발된 코드들에 대해 모든 중복을 제거하며 리팩터링 한다.
이론적으로만 해당 내용을 이해하기 어렵다. 진짜로..
Spring과 같은 프레임워크에 적용하는 것은 다른 영역이고, 이러한 이유로 ATTD(Application TDD)라고 불린다.
테스트 주도 개발(TDD) 접근 방법
- 가짜로 구현하기: 최대한 빨리 테스트를 통과하기 위해 정답이 아닌 가짜 정답을 구현하는 방법
- 삼각측량법: 값이 다른 여러 테스트를 작성하고, 이를 일반화하여 정답을 구현하는 방법
- 명백하게 구현하기: 정답은 바로 구현하는 방법
Spring에서의 테스트 주도 개발(TDD) 프로그래밍 방법
- Repository > Service > Controller 순서로 개발을 진행한다.
- Repository 계층의 테스트는 H2와 같은 인메모리 데이터베이스 기반의 통합 테스트로 진행한다.
- Service 계층의 테스트는 Mockito를 사용해 Repository 계층을 Mock 하여 진행한다.
- Controller 계층의 테스트는 SpringTest의 MockMvc를 사용해 진행한다.
Controller > Service > Repository 순서로 TDD개발하는 경우가 많다. 하지만 Repository부터 계층을 작성해야 TDD의 flow흐름이 좋은 거 같다. Repository 계층은 다른 계층에 대한 의존성이 상대적으로 적기 때문에 Controller부터 개발해도 전혀 문제가 없다. 개인에 맞게 맞춰나가면 된다.
반응형
'IT > Spring' 카테고리의 다른 글
[Spring] Java와 Spring에서 ReentrantLock을 활용한 동시성 제어 (0) | 2024.09.30 |
---|---|
[Spring] 단위 테스트 (Unit Test) (0) | 2024.09.08 |
[Spring] HTTP GET과 POST 개념과 차이점 (0) | 2024.08.12 |
[Spring] HTTP PUT과 PATCH 개념과 차이점 (0) | 2024.07.21 |
[Spring] CollectionUtils.isEmpty() (0) | 2022.06.20 |
Comments