테스트코드를 작성하게되면 항상 들었던 생각
"귀찮은데 굳이 해야되나?", "이거 할 시간에 빨리 기능구현해야되는 거 아니야?"등 테스트코드는
불필요하다는 생각뿐이였다.
그래도 Service layer에 계산하는 로직이 있거나 하는 곳에는 테스트 코드가 있으면 좋겠지~ 라고 생각은 했지만, 굳이 Mock데이터를 만들어서, 입력값에 따른 출력값도 다~~설정해주는데, 왜 하는 거지? 라는 생각뿐이였다.
하지만, 최근 테스트코드를 하나하나 곱씹어가며
"어? 조금은 필요할지도?"라는 생각이 들어가며, 테스트코드에 대한 긍정적인 인식이 생겨가며 글을 써보기러 했다.
테스트코드의 종류
테스트 코드는 가장 작은 테스트부터 이야기 하자면
- 단위 테스트
- 통합 테스트
- 시스템 테스트
- 사용자 인수 테스트
등이 있다.
여기서, 개발자들은 주로 단위 테스트와 통합테스트를 다루게 되는데, 로컬에서 실제 서비스를 실행시켜 PostMan으로 테스트해보는 과정을 보통 통합테스트라 할 수 있다.
그리고 통합테스트는 이방법외에도 여러 방법으로 테스트를 해보기때문에 지금 단계에서는 어려워 다음에 다뤄보고자 한다.
그럼 우리가 주로 다룰게될 테스트는 "단위테스트" 인데, 단위테스트는 뭘까?
단위 테스트란?
단위테스트는 개발적인 코드 단위가 의도한 대로 작동하는지 확인하는 과정을 말한다.
- 서비스의 개별 코드단위(하나의 메소드)를 테스트하여 오류를 발견하고 에러를 미연에 방지할 수 있는 것이다.
- 해당 메소드가 성공할 경우도 있지만, 실패했을 때의 경우도 있기 때문에, 해당 경우의 수를 코드로 만들고 그 경우의 수를 해결하는 과정을 "테스트 케이스"라고 한다.
- 성공의 경우 나올 출력값을 예상해야되고, 실패의 경우도 나올 에러의 값을 예상해야된다.
테스트코드를 작성하는 이유
- 작성해보면서 느낀 것은 작은 프로젝트의 경우,솔직히 테스트코드가 의미 없을 수도 있다.
- 하지만, 조금이라도 내가 정신이 없거나, 조금이라도 내게 큰 프로젝트라고 생각한다면 테스트코드를 작성함으로써, "신경을 끌 수 있는 장점"이 생긴다!
- 이게 이렇게 들으면 좀 막연하여 와닿지않을 수도 있는데, 대표적인 예로 "To-Do-List"가 있다.
(나는 To-Do-List에 많은 덕을 본사람으로써, 본인도 덕을 보았다면 어느정도 이해할 수 있을 것이다.)
여행 To-Do-List
전에 부모님 결혼기념일 30주년을 기념으로 해외여행을 기획한적이 있다.(패키지여행아니고 자유여행으로...)
사실 친구들이랑 간다면야 큰 테마만 가지고 생각없이 다녔겠지만, 부모님을 위한 여행이라하니 신중하게 계획을 하였다.
사실 자유여행에다가 처음가보는 곳이다보니, 무엇을 해야할 지 막막 그자체였는데 일단 하루하루 무엇을 하면 좋을 지 쭈욱~나열하고 동선을 짜다보니, 자연스럽게 하루에 일정의 틀이 잡혔고, 일정을 다 짜게 되었다.
그리고 내 걱정을 덜어준 가장 중요한 것은
"이 나왔던 계획을 하루하루 To-Do-List 마냥 적어놓으니 꽤나 많은 걱정이 덜어졌다. 실제 해외에서 이동할 것처럼 구체적이고 정확할 수록 내 걱정은 점점 덜어졌었다."
- 위 내용은 여행계획의 일부인데 가이드 마냥 상황에따라 읽어가며 해결하니 훨씬 편하게 다녀오게되었다.ㅎㅎ
- 여담으로 예외케이스도 넣어 찾아간 곳이 열려있지않았을 경우도 잘 활용했다 ㅎㅎ
단위 테스트 코드도 마찬가지
- 테스트코드도 똑같은 이유이다. 구체적이고 예외케이스까지 작성할 수록 걱정이 덜어져 다른일에 집중할 수 있게 되는 것이다.
- 물론, 위에 여행계획이 없어도 여행을 다녀올 수 있다.하지만, 그 여행은 과연 걱정이 없는 여행이 될 수 있을까?
- 게다가 테스트 코드를 작성하면서 머리속에 정리가 되는 장점도 있었다. 내가 어디까지 진행했는지, 무엇을 하고 있는지등을 인지하게되고 자연스럽게 다음 할일을 진행하기도 수월해졌다.(사실 블로그도 그래서 씀)
- 이 것은 존재하지않는 것을 실제 동작하게 만드는 개발자에게는 정말 좋은 현상이다.
그러므로 이제부터 테스트코드를 진지하게 임해보고자 한다.
우당탕탕 테스트코드
발생한 문제들
1. 빌드시 마다 QueryDSL의 Q파일이 생성되어 충돌되는 현상
a. 해결하기위해 시도한 방법 : Edit Configurations에서 build option에서 Before launch로 매 실행마다 clean을 동작하게 하는 방법
- 이 방법은 SpringBoot Application을 실행할때는 적용하기 좋았으나, Test코드로 구현할때에는 결과창이 안뜨게되는 버그가 발생했다.(사실 이 버그는 Gradle 빌드때문이였다.)
- 정말 해결의 만능키라 불릴 수 있는 빌드툴을 전환하는 방법이다.
- 애초에 프로젝트를 Gradle로 빌드를 계속해줘도 뭔가 에러가 발생하고, IntelliJ가 먹통이되는 사태까지 발생했었다.
-
이걸로 해결이 되는 이유는 먼저 Gradle
로 빌드하게 되면, Build폴더
가 생성이 되고, IntellJ IDEA
로 빌드하게 되면, out폴더
가 생성이 된다.
-
그래서, IntelliJ로 빌드를 하게되면, Build폴더에 QueryDSL파일이 생겨나도 out폴더를 사용하기에 충돌할 일이 없어지는 것이다!
- 추가적으로 IntelliJ 빌드 방식은
증분빌드
를 사용하여 보다 효율적으로 빌드한다. 참고자료
2. JSON -> java객체 전환기 (Jackson)
- Controller layer를 Test하려면, 기본적으로 API 테스트를 해야함으로, 주고받는 값에 JSON이 필요하다!
- 처음 익숙치않을때는 JSON을 그냥, 문자열로 표현했는데 사실이래도 정상동작한다.
String json = "{\n" +
" \"lane\": \"\",\n" +
" \"queueType\": \"\",\n" +
" \"tier\": \"\",\n" +
" \"isRiotVerified\": false\n" +
"}";
- 하지만, 딱 봤을때 눈에 바로 들어오는 형태가 아니고 매번 문자열로 만들어야하는 번거로움이 있어 알아보니
객체
-> JSON
으로 만들어주는 라이브러리가 있었다.
- 객체를 JSON 문자열로 변환하는 방법은 여러 가지가 있지만, 내장된
Jackson ObjectMapper
을 이용하였다.
Jackson 사용법
- 사용방법은 간단했는데, ObjectMapper를 새로 만들어주고(혹은 자동주입), 미리 만들어놓은 요청 dto를 넣어주면 Json으로 바꿔준다.
import com.fasterxml.jackson.databind.ObjectMapper;
@Autowired
ObjectMapper objectMapper;
DuoRequestDto.DuoSearch duoSearch = new DuoRequestDto.DuoSearch();
String json = objectMapper.writeValueAsString(duoSearch);
3. Json변환과정에서 발생한 또 다른 에러
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type definition error
에러
- 쉽게말해 Jackson라이브러리에서 데이터를 바인딩할 때 나타나는 타입에러이다.
- 에러가 나는 원인은 생각보다 간단한데, 스프링부트에서 대부분의 바인딩하는 기술은 객체는 Public으로 접근 가능하여야하고 내부 필드는 Setter/Getter로 접근하기때문에 기본 생성자가 필요하다.
- 사실 클래스를 처음 만들었을 때, 생성자가 없다면 기본 생성자가 default로 생성이 되지만, 다른 생성자가 있는 경우에는 아무것도없는 기본 생성자를 직접 적어주어야한다.
- [나는..
@NoArgsConstructor
를 추가해주었다.]
우당탕탕 TestCode 작성기 1차 후기
- 정말 많은 곳에서 부딪히게되는 TestCode였다. TestCode만을 구현하기 위해서 알아야할 개념들도 많았고, 테스트과정을 통해 알게된 것도 많지만, 아직 모르는 것이 많은 것같은 미지의 영역인 것 같았다..
- TestCode작성이 좀만 더 간편해지면 좋겠다..
- 하지만, 이번에 Controller단의 TestCode를 예외케이스까지 작성해보면서 검증로직을 검사해볼 수 있음을 깨닫게되어서 걱정을 좀 덜어냄을 체감해봤다 ㅎㅎ
(하지만, 검증로직에서도 또많은 시행착오가..)
그리고 가장 많이 든 생각은 TestCode는 연습이 많이 필요하니, 시간 많을 때 시간을 들여서 해야된다!!