| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- Deadlock
- 다이나믹 프록시
- redis
- BOJ
- 최소 신장 트리
- Junit5
- 객체지향
- 문자열
- Reflection
- 스프링 시큐리티
- 프록시
- spring security
- 자바
- 알고리즘
- 모던 자바 인 액션
- 약수
- 스프링
- 백준
- OS
- MST
- 운영체제
- CS
- Python
- test
- proxy
- Spring
- 모던자바
- java
- 리플렉션
- 파이썬
- Today
- Total
Dev 달팽이 @_''
[리뷰] 테스트 주도 개발 시작하기 본문
[리뷰] 테스트 주도 개발 시작하기

실무에서 개발을 하다보니 테스트가 중요한 지를 깨달았다. 특히 이번 프로젝트처럼 규모가 어느정도 되는 시스템일 경우는 더더욱 중요한 걸 느꼈다.
내가 맡은 서버가 단말 중개 서버(Bridge)였기 대부분의 인입이 프로토콜의 형태로 들어왔고, 비즈니스 로직도 커서 개발하면서 테스트를 진행하는 건 꿈도 못꾸고 있었다.
그렇다 보니 유닛 테스트 부터 통합 테스트까지 제대로 검증을 못한 채로 필드 테스트를 진행했다. 결과는 역시나 .. 여기 저기서 에러가 뻥뻥 터지고 수정하고 터지고 수정하고 오픈까지 이 일의 연속이었다...
그 때 난 이런 생각을 했다.
`이런 시스템은 테스트를 어떻게 하지? 개발하면서 테스트를 충분히 했다면 좀 더 수월하지 않았을까? 내가 다시 돌아간다면 어떻게 테스트를 할 수 있을까?`
그래서 프로젝트를 오픈하고 가장 먼저 집어 든 책이 바로 이 책이다.
리뷰
서론이 길었다. 본격적으로 이 책을 리뷰하자면, 먼저 나는 나같은 주니어에게는 `강추`이다.
물론 TDD에 대해서 모르는 사람은 없을 것이다. 그러나 어떻게 하는 건지 아는 사람은 많이 없을 것이다.
내가 그랬다...
'TDD는 테스트 주도 개발로 테스트 코드를 먼저 짜고 기능을 개발하는 거야! 나도 요즘 트렌드에 맞게 TDD 개발 해봐야겠다!!(IntelliJ를 키고 스프링 부트 프로젝트를 만든 다음 테스트 폴더에 클래스를 하나 일단 만든다.) 음.. 근데 그걸 어떻게 하지? 기능이 없는데 테스트를? 이게 뭔 소리지?'
이게 나의 모습이었다.
이 책은 나에게 시작도 못하던 TDD를 시작할 수 있게 해주는 가이드를 해주었다.
내가 TDD를 시작하지 못했던, 만들어 놓은 코드가 없는데 테스트를 하는 지, 어떤 거 부터 시작하는지 자세하게 알려준다.
아래는 이 책에서 말하는 TDD 절차(방법)이다.
TDD 절차
- 테스트할 대상과 케이스 선택
- 해당 테스트에 대한 테스트 케이스 코드 작성
- 컴파일 오류를 없애는데 필요한 클래스와 메소드 등을 추가한다.
- 테스트가 통과되도록 구현한다.(처음엔 하드 코딩 등)
- 4번에서 구현한(하드 코딩 등) 목록을 일반화(구체적으로)하여 구현한다.
- 테스트를 통과했다면 5번의 코드를 리팩토링 요소를 찾아 리팩토링을 한다.
- 모든 테스트가 통과하는지 확인한다.
- 새로운 케이스를 선정 후 반복하여 점진적으로 코드를 완성해 나간다.
여기까지 보면 정말 간단하고 쉽게 시작이 가능하다.
그러나, 내가 이걸 보면서 생각하는 게 있었다.
'아 시작은 이제 어떻게 하는지 알겠는데.. 내가 진행한 프로젝트는 DB작업도 많고, 외부 연동도 많고, 얽히고 설킨게 많은데 이게 가능한거야? 실제 실무에서 사용하려면 어떻게 해야하는거지?'
신기하게도 이런 생각하면서 의심 반, 걱정 반 하며 읽을 때 쯤 필자가 먼저 얘기를 꺼낸다.
`실제로 실무에서는 외부 연동이나 DB Connection 등 테스트하기 힘들게 만드는 외부 요소들이 존재한다. 이럴 때는 '대역'을 사용한다`
대역에는 스텁(Stub), 가짜(Fake), 스파이(Spy), 모의(Mock)이 있다.
이를 사용하여 테스트가 힘든 외부 요인이나 결과를 대체한다. 하지만, 대역을 사용할 때 주의해야 하는 사항들이 존재한다.
- 모의 객체를 과하게 사용하면 오히려 테스트 코드가 복잡해질 수 있다.
- 결과 값을 확인하는 수단으로 모의 객체를 사용하면 결과 검증 코드가 길어지고 복잡해진다.
- 모의 객체는 기본적으로 메서드 호출 여부를 검증하는 수단이므로, 테스트 대상과 모의 객체 간의 상호 작용이 조금만 바뀌어도 테스트가 깨지기 쉽다.
- DAO나 리포지토리와 같은 저장소에 대한 대역은 모의 객체보다 메모리를 이용한 가짜 구현을 사용하는 편이 코드의 간결성과 유지보수성에서 더 좋다.
여기까지는 TDD의 방법을 주로 다뤘으면 다음 장 부터는 테스트를 위한 설계 관점을 다룬다.
테스트를 위한 설계를 하기 위해서는 꽤 많은 부분을 신경써야한다.
테스트가 가능 설계는 다음과 같다.
- 하드 코딩된 상수를 생성자나 메서드 파라미터로 받는다.
- 의존 대상을 주입 받는다.
- 의존 대상은 생성자 주입으로 교체할 수 있도록 만든다.
- 의존 대상을 교체할 수 있게 되면 실제 구현 대신에 대역을 사용할 수 있어 테스트가 수월해진다.
- 테스트하고 싶은 코드를 분리한다.
- 기능의 일부만 테스트하고 싶은 경우, 해당 코드를 별도 기능으로 분리해서 테스트를 진행 할 수 있다.
- 시간이나 임의 값 생성 기능을 분리한다.
- 테스트 대상이 사용하는 시간이나 임의 값을 제공하는 기능을 별도로 분리해서 테스트 가능성을 높일 수 있다.
- 외부 라이브러리는 직접 사용하지 말고 감싸서 사용한다.
마지막으로 테스트 코드도 유지보수의 대상이다. 테스트 코드의 유지보수성을 높히기 위한 방법에 대해 소개한다.
이 책을 읽고 `그럼 이제 TDD 방법은 알았으니까 이제 실무에서 TDD를 적용해서 개발 할 수 있을까?` 라는 생각을 해보았을 때, 내 대답은 `흠.. 글쎄.. 간단한 거 정도는 해볼 수 있지 않을까?` 이다.
이런 생각을 한 나에게 이 책의 필자는 마지막에 이런 말을 한다.
`물론 100% TDD로 개발할 수는 없겠지만 할 수 있는 한 많은 범위를 TDD로 개발하는 것이 중요하다.`
`처음엔 쉬운 것을 TDD로 시도해서 TDD에 익숙해지고 이후에 점진적으로 TDD 적용 범위를 늘려나가자.`
필자의 말 처럼 모든 걸 TDD를 할 필요는 없다. 내가 가능한 간단한 거 정도로 부터 시작하면 언젠간 TDD가 주는 효과를 느낄 수 있지 않을까 싶다.
이 책에 대한 내용과 내 생각은 이 글 하나에 담기엔 역부족하다.
내용이 어렵지 않으니 나같은 주니어라면 기회되면 한번은 읽으면 좋을 거 같다.