220 likes | 410 Views
2.4 스프링 테스트 적용. 2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리. 현재까지의 문제점 애플리케이션 컨텍스트 생성의 중복 @Before 메소드는 @Test 메소드 개수 만큼 수행되기 때문에 애플리케이션 컨텍스트 생성도 그만큼 수행됨 추후 빈이 많아지면 애플리케이션 컨텍스트 생성 수행시간도 길어짐 스프링 테스트 컨텍스트 프레임워크 적용 @ RunWith 와 @ ContextConfiguration 애노테이션 적용. 2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리.
E N D
2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리 • 현재까지의 문제점 • 애플리케이션 컨텍스트 생성의 중복 • @Before 메소드는@Test 메소드 개수 만큼 수행되기 때문에 애플리케이션 컨텍스트 생성도 그만큼 수행됨 • 추후 빈이 많아지면 애플리케이션 컨텍스트 생성 수행시간도 길어짐 • 스프링 테스트 컨텍스트 프레임워크 적용 • @RunWith와 @ContextConfiguration애노테이션 적용
2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리 • 테스트 메소드의컨텍스트 공유 • @Before setUp() 메소드 추가 • 실행시 콘솔 출력결과 • context (애플리케이션 컨텍스트) 객체는 모두 동일 • UserDaoTest객체는 매번 다름 • @Test 메소드를 실행할 때마다 테스트 객체를 새로 생성
2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리 • 테스트 클래스간의 컨텍스트 공유 • 여러 개의 테스트 클래스가 모두 같은 설정파일을 지닌 애플리케이션 컨텍스트를 사용한다면, 단지 한 개의 애플리케이션 컨텍스트 객체를 생성하고 여러 클래스가 공유한다.
2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리 • @Autowired • @Autowired가붙은 인스턴스 변수가 있으면그 변수 타입과 일치하는 컨텍스트 내의 빈을 찾아 할당해줌 • 별도의 DI 설정 없이 자동 와이어링 • UserDao빈의 자동 와이어링 처리
2.4.1 테스트를 위한 애플리케이션 컨텍스트 관리 • @Autowired • XML에 dataSource이름으로 등록한 SimpleDriverDataSource타입 빈을 DI 받기 위한 코드 • 타입 이름을 인터페이스 이름인 DataSource로 선언해도 됨 • DI 받을 때 타입 선언: 인터페이스 이름 vs. 구체적인 클래스 이름? • DataSource에 선언된 일반적인 메소드 호출에만 관심이 있다면 인터페이스 이름으로 선언 추천 • dataSource빈의 구현 클래스가 변경되어도 DI 문제 없음 • 가능하면 인터페이스 선언 사용 추천 • 구체적인 클래스가 지니고 있는 특정 메소드 호출에 관심이 있다면 클래스 이름으로 선언
2.4.2 DI와 테스트 • 인터페이스를 사이에 두고 DI를 사용하는 이유 • 인터페이스 타입인 UserDao변수로 DI 받는 이유 (왜 구체적인 SimpleDriverDataSource를 타입으로 선언하지 않았나?) • 1) 소프트웨어 개발시에 구체적인 클래스가 변경되어도 코드 수정이 없다. • 다른 부가기능 및 새로운 서비스 기능 도입시에새로운 클래스로 구현될 가능성이 높음 • 이런 경우 새로운 클래스 작성 후 xml만 수정하면 됨 • 3) JUnit테스트에서는 DI를적극적으로 활용한다. • 다음 페이지 참고
2.4.2 DI와 테스트 • 테스트 코드에 의한 DI • 실제 운영 DB에 연결을 하는 dataSource는 테스트시에 사용하면 절대 안됨 • 즉, 테스트 시에는 다른 곳에서 운영되는 DB (예, 로컬DB)로 연결하는 dataSource객체를 DAO가 사용하도록 해야 함 • SingleConnectionDataSource • 테스트 때 많이 사용하는 빠른 연결을 보장하는 DataSource
2.4.2 DI와 테스트 • 테스트 코드에 의한 DI • @DirtiesContext애노테이션 • 스프링의 테스트 프레임워크에게 해당 클래스 (또는 메소드)의 테스트에서 현재 사용중인 애플리케이션 컨텍스트를 공유하지 않게 함 • 본 테스트가 끝나고 다른 테스트가 시작되면 원래의 애플리케이션 컨텍스트가다시 생성되어 활용됨 • 즉, 테스트 중에 변경되어질 수 있는 상황이 다른 테스트에 영향을 주지 않도록 보장해줌 • 하지만, @DirtiesContext애노테이션은 많이 사용되지 않음 • 다음 페이지 참조
2.4.2 DI와 테스트 • 테스트를 위한 별도의 DI 설정 • 테스트 전용의 애플리케이션 컨텍스트 설정 파일 생성 • test-applicationContext.xml • 테스트시에 테스트용설정 파일 적용
2.4.2 DI와 테스트 • 컨테이너 없는 DI 테스트 • 스프링의비침투적 (Noninvasive) 특성 사용 • 스프링의 애플리케이션 컨테이너에 전혀 의존적이지 않은 테스트 • @RunWith와 @ContextConfiguration애노테이션 사용하지 않음 • @Autowired애노테이션 사용하지 않음
2.4.2 DI와 테스트 • 컨테이너 없는 DI 테스트 • 장점 • 전체적으로 애플리케이션 컨텍스트를 전혀 활용하지 않는다면 테스트 수행속도 높아짐 • 코드가 스프링에 의존하지 않으므로 더욱 깔끔함
2.4.2 DI와 테스트 • DI를 이용한 테스트 방법 선택 • 스프링 컨테이너 없이 테스트할 수 있는 방법을 우선적으로 고려 • 스프링 컨테이너에 의존하는 테스트를 해야 할 때 • 여러 객체들이 복잡한 의존관계를 지니고 있는 경우 • 이런 경우 스프링의 설정을 이용한 DI 방식의 테스트가 유리 • 테스트에만 임시적으로 예외적인 의존관계가 필요한 경우 • @DirtieContext애노테이션 사용 • 하지만, 테스트를 위한 별도의 XML 설정 파일 사용 추천
2.5.0 학습 테스트란? • 학습 테스트 (Learning Test) • 자신이만들지 않은 프레임워크나 다른 개발팀에서 만들어서 제공한 라이브러리 등에 대한 테스트 • 학습 테스트의 목적 • 자신이 사용할 API나 프레임워크의 기능을 “테스트”하면서 그 사용방법을 익히려는 것 • 때로는 어설프게 알고 있거나 오해라고 있는 지식을 “테스트”를 만드는 과정을 통해 바로잡기 위함
2.5.1 학습 테스트의 장점 • 학습 테스트의 장점 • 다양한 조건에 따른 기능을 손쉽게 확인 가능 • 예제를 통한 학습보다 더 다양한 조건에 따라 어떻게 기능이 다르게 동작하는지 확인 가능 • 학습 테스트 코드를 개발 중에 참고 가능 • 학습 테스트 작성 이후 샘플 코드로서 참고 가능 • 프레임워크 제품을 업그레이드할 때 호환성 검증을 도와줌 • 기존에 사용하던 API나 기능에 변화가 있거나 업데이트된 제품에 버그가 있다면 학습 테스트를 통해 미리 확인 가능 • 테스트 작성에 대한 좋은 훈련이 됨 • 스프링 학습 테스트 • 스프링 학습 테스트 작성시 참고할 수 있는 가장 좋은 소스 • 스프링 자신에 대한 테스트 코드
2.5.2 학습 테스트 예제 • JUnit테스트 객체 테스트 • JUnit테스트 메소드수행시 새로운 객체생성 테스트
2.5.2 학습 테스트 예제 • JUnit테스트 객체 테스트 • JUnit테스트 메소드수행시 새로운 객체생성 테스트 (개선)
2.5.2 학습 테스트 예제 • 스프링 테스트 컨텍스트 테스트 • 애플리케이션 컨텍스트의 여러 메소드에서의공유 테스트 • 등록된 빈이 없는설정 파일 마련 • 테스트 코드 (1/2)
2.5.2 학습 테스트 예제 • 스프링 테스트 컨텍스트 테스트 • 애플리케이션 컨텍스트의 여러 메소드에서의공유 테스트 • 테스트 코드 (2/2) • 세가지의 검증방법
2.5.3 버그 테스트 • 버그 테스트 (bug test) • 코드에오류가 있을 때 그 오류를 가장 잘 드러낼 수 있는 테스트 • 버그가 원인이 되어 테스트가 실패하는 코드를 우선 작성 • 그 다음 테스트가 성공할 수 있도록 애플리케이션 코드 수정
[실습] • 다음을 검증 할 수 있는 학습 테스트 작성 • 1) userDao 스프링 빈은 싱글톤 방식으로 객체가 생성됨을 검증 • 2) @Autowired로 DI 받은 userDao객체가 애플리케이션 컨텍스트에서 직접 getBean()으로 가져온 객체와 동일한지 검증