Study with book/토비의 스프링 3.1

2장. 테스트


스프링 개발자에게 제공하는 가장 중요한 가치는 객체지향과 테스트이다.

 

2.1 UserDaoTest 다시 보기

2.1.1 테스트의 유용성

테스트란 내가 예상하고 의도했던 대로 코드가 정확히 동작하는지를 확인해서 만든 코드를 확실할 수 있게 해주는 작업이다.

 

2.1.2 UserDaoTest의 특징

웹을 통한 DAO 테스트 방법의 문제점

 - 테스트하고 싶었던 것은 UserDao였는데, 다른 계층의 코드와 컴포넌트, 심지어 서버의 설정 상태까지 모두 테스트에 영향을 줄 수 있기 때문에 이런 방식으로 테스트하는 것은 번거롭고 오류가 있을 때 빠르고 정확하게 대응하기가 힘들다.

 

작은 단위의 테스트

테스트하고자 하는 대상이 명확하다면 그 대상에만 집중해서 테스트하는 것이 바람직하다. 이렇게 작은 단위의 코드에 대해 테스트를 수행한 것을 단위 테스트라고 한다. 하지만 그 범위는 정해지지 않는다. 단위 테스트를 하는 이유는 개발자가 설계하고 만든 코드가 원래 의도한 대로 동작하는지를 개발자 스스로 빨리 확인 받기 위해서다.

 

자동수행 테스트 코드

테스트는 자동으로 수행되도록 코드로 만들어지는 것이 중요하다. 테스트 자체가 사람의 수작업을 거치는 방법(db table 지우기)을 사용하기보다는 코드로 만들어져서 자동으로 수행될 수 있어야 한다.

 

지속저인 개선과 점진적인 개발을 위한 테스트

테스트를 이용하면 새로운 기능도 기대한 대로 동작하는지 확인할 수 있을 뿐 아니라, 기존에 만들어뒀던 기능이 새로운 기능을 추가하느라 수정한 코드에 영향을 받지 않고 여전히 잘 동작하는지를 확인할 수도 있다.

 

2.1.3 UserDaoTest의 문제점

수동 확인 작업의 번거로움

 - 콘솔에 나온 값을 보고 등로고가 조회가 성공적으로 되고 있는지를 확인하는 건 사람의 책임이다. 때문에 완전히 자동으로 테스트되는 방법이라고 말할 수 없다.

실행 작업의 번거로움

 - main() 메소드가 한 개여서 테스트가 쉽지만 그게 몇 백개라면 일일히 확인하는 것도 번거롭다.

2.2 UserDaoTest개선

2.2.1 테스트 검증의 자동화

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/1.5.1

모든 테스트는 성공과 실패 두 가지 결과를 가질 수 있다. 테스트의 실패는 테스트가 진행되는 동안 에러가 발생해서 실패하는 경우와 테스트 작업 중에 에러가 발생하지 않았지만 그 결과가 기대한 것과 다르게 나오는 경우로 구분해 볼 수 있다.

 

2.2.2 테스트의 효율저인 수행과 결과 관리

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.2.2

2.3 개발자를 위한 테스팅 프레임워크 JUnit

2.3.1 JUnit 테스트 실행 방법

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.3.1

 

2.3.2 테스트의 결과의 일관성

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.3.1

단위 테스트는 코드가 바뀌지 않는다면 매번 실행할 때마다 동일한 테스트 결과를 얻을 수 있어야 한다.

 

2.3.3 포괄적인 테스트

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.3.3

테스트는 어떤 순서로 실행될지는 알 수 없다. JUnit이 실행 순서를 보장해주지 않는다. 테스트 결과가 실행 순서에 영향을 받는다면, 그것은 잘못 만든 테스트 코드이다.

 

2.3.4 테스트가 이끄는 개발

새로운 기능을 넣기 위해서 UserDao 코드를 수정하고 그런 다음 수정한 코드를 검증하기 위해 테스트를 만드는 순서로 진행한 것이 아니다. 반대로 테스트를 먼저 만들어 테스트가 실패하는 것을 보고 나서 UserDao의 코드에 손을 대기 시작했다. 테스트를 성공하게 해주는 코드를 작성하는 방식의 개발이 테스트 주도 개발(TDD)이다.

 

2.3.5 테스트 코드 개선

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.3.5

JUnit 개발자는 각 테스트가 서로 영향을 주지 않고 독립적으로 실행됨을 확실히 보장해주기 위해 매번 새로운 오브젝트를 만들게 했다. 덕분에 인스턴스 변수도 부담 없이 사용할 수 있다.

 

2.4 스프링 테스트 적용

2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.4.1

테스트는 가능한 한 독립적으로 매번 새로운 오브젝트를 만들어서 사용하는 것이 원칙이다. 하지만 애플리케이션 컨텍스트처럼 생성에 많은 시간과 자원이 소모되는 경우에는 테스트 전체가 공유하는 오브젝트를 만들기도 한다. 이때도 테스트는 일관성 있는 실행 결과를 보장해야 하고, 테스트의 실행 순서가 결과에 영향을 미치지 않아야 한다.

 

2.4.2 DI와 테스트

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.4.2

그냥 UserDao에서 직접 SimpleDriverDataSource를 생성하고 사용하면 안될까? 하는데 그래도 인터페이스를 두고 DI를 적용해야 한다. 그 이유는 아래와 같다.

첫째, 소프트웨어 개발에서 절대로 바뀌지 않는 것은 없기 때문이다.

둘째, 클래스의 구현 방식은 바뀌지 않는다고 하더라도 인터페이스를 두고 DI를 적용하게 해두면 다른 차원의 서비스 기능을 도입할 수 있기 때문이다.

셋째, 테스트 때문이다. 효율적인 테스트를 손쉽게 만들기 위해서라도 DI를 적용해야 한다.

2.5 학습 테스트로 배우는 스프링

2.5.1 학습 테스트의 장점

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.4.1

1. 다양한 조건에 따른 기능을 손쉽게 확인해볼 수 있다.

2. 학습 테스트 코드를 개발 중에 참고할 수 있다.

3. 프레임워크나 제품을 업그레이드할 때 호환성 검증을 도와준다.

4. 테스트 작성에 대한 좋은 훈련이 된다.

5. 새로운 기술을 공부하는 과정이 즐거워진다.

 

2.5.2 학습 테스트 예제

실습 코드 링크: https://github.com/vvshinevv/toby-spring/tree/feature/2.5.2

 

2.5.3 버그 테스트

버그 테스트랑 코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트를 말한다. 버그 테스트는 일단 실패하도록 만들어야 한다. 버그가 원인이 돼서 테스트가 실패하는 코드를 만드는 것이다. 그 장점으로는 아래와 같다.

1. 테스트의 완성도를 높여준다.

2. 버그의 내용을 명확하게 분석해준다.

3. 기술적인 문제를 해결하는데 도움이 된다.


[참고자료]

토비 스프링 vol.1 - 이일민

'Study with book > 토비의 스프링 3.1' 카테고리의 다른 글

4장. 예외  (0) 2020.03.29
3장. 템플릿2  (0) 2020.03.22
3장. 템플릿1  (0) 2020.03.22
1장. 오브젝트 의존관계2  (0) 2020.03.15
1장. 오브젝트 의존관계1  (0) 2020.03.08