1. 단위테스트의 가치
테스트의 가치
- 테스트 코드를 만들어야 스프링이 지원하는 가치를 누릴 수 있다. 테스트 코드가 없었다면 지금의 스프링 자신도 없었을 것이다.
- 테스트 코드는 개발자의 행복과 관련이 있다. 테스트 코드는 내가 만든 코드를 확신할 수 있게 하고, 마음에 안정감을 준다. 테스트 코드는 변화(코드 구조, 설계, 기술 등)에 유연하게 대처할 수 있는 자신감을 준다.
단위테스트
- 웹을 통해 테스트를 하면 테스트하려는 대상 이외에 많은 것들이 준비되어야 한다. 그래서 즉시 테스트할 수 없고 문제가 발생하면 테스트하려는 대상의 문제인지 다른 환경의 영향인지 구분하기가 어렵다.
- 단위 테스트는 테스트하는 관심 대상에 집중한다. 관심 대상 이외는 참여하지 않도록하고 외부의 리소스에 가능한 의존하지 않도록 한다. 그래서 문제가 발견되면 원인을 한정하기 쉽다. 개발자는 이 단위 테스트를 통해 컴퓨터에게 반드시 확인을 받아야 한다.
2. 더 나은 테스트 코드를 위해
자동화된 테스트
- 수동으로 테스트를 하면 귀찮은 마음이 은연중에 생기고 테스트 하려는 마음을 접어버리곤 한다.
- 테스트를 자동화화면 빠르게 테스트를 할 수 있어 쉽게 자주 반복할 마음이 생긴다.
점진적인 개선을 위한 테스트
- 일단 자신 있게 만들 수 있는 가장 간단한 방법으로 코드를 만들자 마자 테스트 코드를 만들어 두자. 그때부터 자신있게 조금씩 코드를 개선해 나갈 수 있다.
- 처음부터 완벽한 코드를 다 만들고 검증하려 한다면 나중에 쏟아지는 에러 메시지에 무엇부터 살펴봐야 할지 막막해 질지 모른다.
자동 결과 확인
- 테스트 실행 뿐 아니라 테스트 결과를 확인하는 것도 자동화 되어야 한다.
체계적인 테스트 실행과 관리
- 테스트를 실행하는 것과 수 많은 테스트 결과를 관리하는 것도 프레임워크의 도움을 받아 체계적으로 관리될 필요가 있다.
테스트 결과의 일관성
- 우리가 제어할 수 있는 테스트 외부 요소를 적절히 제어함으로 동일한 테스트 입력에 대해 동일한 테스트 결과를 보장하도록 해야한다.
- 코드에 변경사항이 없다면 테스트는 동일한 입력에 대해 항상 동일한 결과를 내야한다.
포괄적인 테스트
- 테스트를 안 만드는 것보다 성의 없이 테스트를 만들어 문제가 있는 코드인데도 테스트가 성공하게 만드는 건 더 위험하다.
- 포괄적이다는 것은 전체 기능을 테스트한다는 관점에서 포괄적일 수 있겠고, 한 가지 기능이 가진 여러 상황에 대한 케이스를 테스트 한다는 관점에서도 포괄적이라고 할 수 있겠다.
- 두 경우 모두에 충실하지 않으면 우리의 테스트는 마치 하루에 두 번은 정확히 맞는다는 시계와 같을 수도 있다. 죽은 시계 말이다.
- 포괄적인 테스트를 통해 내가 수정한 코드가 애플리케이션 전체에 어떤 영향을 주지는 않는지 불안함을 덜 수 있다. 우리는 자신있게 코드를 수정하고 안정감을 가질 수 있다.
인터페이스를 통한 DI
- 소프트웨어 개발에서 절대로 바뀌지 않는 것은 없다. 클래스 대신 인터페이스를 사용하고, new 대신 DI를 통해 주입 받게 하는 작업은 매우 단순하고 쉬운 작업이다. 습관을 가지자. 언젠가 변경이 발생하면 수정에 들어가는 시간과 비용을 줄여줄 것이다.
- 인터페이스를 통해 DI를 수행하면 데코레이션 패턴을 적용해 부가기능을 추가하기 쉽다. 기존에 서비스를 제공하는 쪽과 사용하는 쪽 모두 아무런 변경 없이 부가 기능을 중간에 삽입할 수 있다. AOP가 이런 경우이다. AOP는 애초에 DI를 적용하지 않았다면 불가능했을 것이다.
3. 테스트 응용
테스트가 주도하는 개발
- 실패하는 테스트 코드를 만들고 테스트를 통과하도록 코드를 작성하는 방법이다.
- 개발하려는 기능이 어떠해야 함을 일반 언어가 아니라 테스트 코드로 표현하는 방식이라고 할 수 있다. 뿐만아니라 곧바로 이 테스트 코드로 구현 이후 동작을 검증할 수 있다.
- 실패한 테스트를 성공시키기 위한 목적이 아닌 코드는 만들지 않는 효과가 있다.
- 코드를 만들고 테스트를 수행하는데 걸리는 시간이 0에 가까워 진다. 그래서 코드에 대한 피드백을 매우 빠르게 받을 수 있는 장점이 있다.
- 테스트 없이 한 번에 많은 코드를 만드는 것은 좋지 않다. 테스트 코드를 작성하고 가능한 빨리 실행할 수 있도록 적당한 크기의 모듈을 개발해야 한다.
학습 테스트
- 내가 작성한 코드를 테스트하는 것이 아니라 내가 사용하는 프레임워크의 기능을 확인하고 학습하기 위한 테스트 코드를 작성한다.
- 프레임워크에 대한 이해도를 높일 수 있고, 내 이해의 오류를 교정해 준다.
- 팀에서 공유하고 재사용하기도 좋다.
버그 테스트
- 시스템에 문제가 발생했을 때 해당 문제를 가장 잘 표현하는 방법으로 문제가 재현되는 테스트 코드를 작성해 두는 것이다.
- 역시 실패하는 (버그가 발생하는) 테스트 케이스를 먼저 작성해 두고 문제가 제거되도록 서비스 코드를 수정해 나가는 방법이다.
- 생각만 하는 것이 아니라 코드를 통해 문제에 접근하며 문제의 원인을 바르게 이해하게 되는 효과가 있다.
토비의 스프링 | 2장 테스트 (느낌점, Q&A)