학습 목표
테스트란 무엇이며, 그 가치와 장점, 활용 전략, 스프링과의 관계를 살펴보자.
테스트의 유용성
1장에서 만든 UserDao가 기대했던 대로 동작하는지 확인하기 위해 간단한 테스트 코드를 만들었다. main() 메소드를 이용해 UserDao 오브젝트의 add()와 get() 메소드를 호출해서 그 값을 출력해 눈으로 확인했다. 그 매 단계에서 확인한 덕분에
초난감 DAO 코드를 개선했고 스프링을 적용해서 동작하게 만들 수도 있었다.
테스트란 결국 내가 예상하고 의도했던 대로 코드가 정확히 동작하는지 확인해서, 만든 코드를 확신할 수 있게 해주는 작업이다.
원하는 결과가 나오지 않으면 디버깅 과정을 거쳐서 최종적으로 모든 결함이 제거됐다는 확신을 얻을 수 있다.
UserDaoTest의 특징
1장에서 만들었던 main() 메소드로 작성된 테스트 코드를 다시 살펴보면서 2장을 들어가자.
UserDaoTest를 실행했을 때, 계속 IOException 에러가 나서 해결하느라 꽤나 고생을 했는데 XML 파일 위치를 바꿨더니 쉽게 해결했다. 혹시 같은 에러 때문에 고생하고 있다면XML 파일의 위치를 src/main/java 바로 밑으로 옮겨보는 것을 추천하겠다.
실행해보면 아래와 같이 잘 실행되는 것을 확인할 수 있다.
이 테스트 코드의 내용을 정리해보면 다음과 같다.
- 자바에서 가장 손쉽게 실행 가능한 main() 메소드를 이용한다.
- 테스트할 대상인 UserDao의 오브젝트를 가져와 메소드를 호출한다.
- 입력 값을 직접 코드에서 만들어 넣어준다.
- 테스트 결과를 콘솔에 출력한다.
- 각 단계의 작업이 에러 없이 끝나면 콘솔에 성공 메시지를 출력해준다.
이 테스트 방법에서 돋보인 것은 main() 메소드를 이용해 쉽게 테스트를 수행했고, 테스트할 대상인 UserDao를 직접 호출해서 사용한다는 점이다.
웹을 통한 DAO 테스트 방법의 문제점
보통 웹 화면을 통해 값을 입력하고 기능을 수행하고 결과를 확인하는 방법은 가장 흔히 쓰이는 방법이지만, DAO에 대한 테스트로서는 단점이 너무 많다. 모든 레이어의 기능을 다 만들어야 테스트가 가능하다는 점이 가장 큰 문제이다.
테스트 중 에러가 나면 어디서 문제가 발생했는지 찾는 수고도 필요하다. 그렇다면 테스트를 어떻게 만들면 이런 문제를 피할 수 있고, 효율적으로 테스트를 활용할 수 있을지 생각해보자.
작은 단위의 테스트
테스트는 가능하면 작은 단위로 쪼개서 집중해서 할 수 있어야 한다. 관심사의 분리가 여기에도 적용된다.
UserDaoTest는 한 가지 관심에 집중할 수 있게 작은 단위로 만들어진 테스트다. 그렇기 때문에 에러가 나도 빠르게 원인을 찾을 수 있다. 이렇게 작은 단위의 코드에 대해 테스트를 수행한 것을 단위 테스트 unit test라고 한다.
여기서 말하는 단위는 크기와 범위가 정해준 건 아니다. 그러므로 개인마다 단위라고 생각하는 기준이 다르다.
일반적으로 단위는 작을수록 좋다. 하지만 언젠가는 길고 많은 단위가 참여하는 테스트도 필요하다. 그럼에도 단위별로 테스트를 먼저 수행하고 긴 테스트를 시작한다면 예외가 발생하고 테스트에 실패할 수도 있지만 훨씬 나을 것이다.
단위 테스트는 주로 개발자가 만든 코드를 스스로 확인하기 위해서 사용하는데, 그래서 이를 개발자 테스트 또는 프로그래머 테스트라고도 한다. 물론 개발자가 아닌 전문 테스터나 고객이 단위 테스트를 할 수도 있다. 이때는 단위가 제법 커질 것이고 이미 개발자가 코드를 작성하고 한참 뒤일 것이다. 이 상황에서 버그를 수정하려고 하는 것보다 코드를 만들자마자 빠르게 테스트를 하는 것이 버그를 수정하는 것이 더 빠를 것이다.
자동 수행 테스트 코드
UserDaoTest는 테스트할 데이터가 코드를 통해서 제공되고, 테스트 작업 역시 코드를 통해 자동으로 실행한다는 점이다. 웹 화면에 폼을 띄우고 매번 UserVO의 등록 값을 스스로 입력하고 버튼을 누르는 작업을 반복하면 매우 불편할 것이다.
그러므로 테스트는 자동으로 수행되도록 코드로 만들어지는 것이 중요하다. 굳이 모든 클래스에 main() 메소드에 테스트 코드가 들어가 있을 필요는 없겠지만, 테스트 자체가 수작업을 거치는 것보다 코드로 만들어져서 자동으로 수행될 수 있어야 한다는 건 매우 중요하다.
자동으로 수행되는 테스트의 장점은 자주 반복할 수 있다는 것이다. 번거로운 작업이 없기 때문에 언제든 코드를 수정하고 테스트를 해볼 수 있다. 그렇기 때문에 개발을 완료하고 운영 중인 상황에서 코드르 수정하려면 아무리 간단한 수정이라도 심각한 문제를 일으키지 않을까 하는 두려움이 발생한다. 그럴 때 만들어둔 기능에 대한 테스트가 있다면 수정 후 빠르게 전체 테스트를 수행해서 수정으로 다른 기능에 문제가 발생하지 않는지 확인하고 성공한다면 마음에 확신을 얻을 수 있다.
지속적인 개선과 점진적인 개발을 위한 테스트
초난감 DAO 코드를 스프링을 이용한 깔끔하고 완성도 높은 객체지향적 코드로 발전시키는 과정의 일등 공신이 바로 테스트였다. DAO코드를 만들자마자 바로 기능에 문제가 없는지 검증해주는 테스트 코드를 만들어뒀기 때문에 코드를 개선해 나가는 작업을 진행할 수 있었다.
만약 처음부터 스프링을 적용하고 XML로 설정을 만들고 모든 코드를 작성한 뒤 이를 검증했다면 수많은 에러 메시지에 난감할 수도 있다. 버그를 수정하는데 적지 않은 고민스러운 시간을 보내야 했을 것이다. 하지만 일단 단순하게 정상 동작하는 코드를 만들고, 테스트를 만들어 뒀기 때문에 작은 단계를 거치면서 계속 코드를 개선해나갈 수 있었다.
테스트를 이용하면 새로운 기능도 기대한 대로 동작하는지 확인할 수 있을 뿐 아니라, 기존에 만들어뒀던 기능들이 새로운 기능을 추가하느라 수정한 코드에 영향을 받지 않고 여전히 잘 동작하는지 확인할 수도 있다.
UserDaoTest의 문제점
1. 수동 확인 작업의 번거로움
테스트를 수행하는 과정과 입력 데이터의 준비를 모두 자동으로 진행하도록 만들어졌다. 하지만 여전히 사람의 눈으로 확인하는 과정이 필요하다. 입력한 값과 가져오는 값이 일치하는지 테스트 코드는 확인해주지 않는다. 다만 콘솔에 값만 출력해줄 뿐이다. 그 값을 보고 성공했다고 판단하는 건 사람의 몫이다. 그러므로 완전히 자동으로 테스트되는 방법이라고 말할 수 없다.
2. 실행 작업의 번거로움
간단한 main() 메소드라고 하더라도 매번 그것을 실행하는 것은 제법 번거롭다. 만약 DAO가 수백 개가 되고 그에 대한 main() 메소드도 그만큼 만들어진다면, 전체 기능을 테스트해보기 위해 main() 메소드를 수백 번 실행하는 수고가 필요하다. 그래서 main() 메소드를 이용하는 방법보다 좀 더 편리하고 체계적으로 테스트를 실행하고 그 결과를 확인하는 방법이 절실히 필요하다.
'Spring > 토비의 스프링 정리' 카테고리의 다른 글
2.5 학습 테스트로 배우는 스프링 (0) | 2022.04.06 |
---|---|
2.4 스프링 테스트 적용 (0) | 2022.04.05 |
2.3 개발자를 위한 테스팅 프레임워크 JUnit (2) | 2022.04.04 |
2.2 UserDaoTest 개선 (0) | 2022.04.01 |
1장 오브젝트와 의존관계 (0) | 2022.03.31 |