Spring/토비의 스프링 3.1
2.5 학습 테스트로 배우는 스프링
다비드박
2019. 1. 17. 19:24
2.5 학습 테스트로 배우는 스프링
학습 테스트
자신이 만들지 않은 프레임워크나 다른 개발팀에서 만들어서 제공한 라이브러리 등에 대해서 작성한 테스트
학습 테스트의 목적
- 사용할 API나 프레임워크의 기능을 테스트로 보면서 사용 방법을 익히기 위함
- 자신이 테스트를 만들려고 하는 기술이나 기능에 대해 얼마나 제대로 알고 있는 지를 검증
- 빠르고 정확하게 사용법을 익히기 위함
테스트 대상보다 테스트 코드 자체에 관심을 가져야 함
2.5.1 학습 테스트의 장점
- 다양한 조건에 따른 기능을 손쉽게 확인 가능
- 자동화된 테스트 코드로 만들어지기 때문에 다양한 조건에 따라 기능이 어떻게 동작하는지 빠르게 확인이 가능
- 학습 테스트 코드를 개발 중 참고 가능
- 예제를 만드는 방법의 경우 최종 수정 예제만 남게 된다.
- 학습 테스트는 코드를 개별적으로 만들고 남겨둘 수 있으므로 개발 중 좋은 참고 자료가 된다.
- 프레임워크 또는 제품 업그레이드 시 호환성 검증을 도와줌
- 기존에 사용하던 API가 기능에 문제가 없다는 사실을 미리 확인해 볼 수 있음.
- 기능에 변화가 있거나 업데이트 된 제품에 버그가 있다면, 미리 확인할 수 있음
- 사용법에 변화가 생긴 경우 그에 맞춰 애플리케이션 코드를 수정할 계획을 세울 수 있음
- 테스트 작성에 좋은 훈련이 된다.
- 테스트 코드 작성을 연습할 수 있다,
- 학습 테스트의 경우 한두 가지 간단한 기능에만 초점을 맞추면 되기 때문에 테스트도 대체로 단순하다.
- 새로운 기술을 공부하는 과정이 즐거워진다.
스프링 학습 테스트 시 참고할 수 있는 가장 좋은 소스 : 스프링 자신에 대한 테스트 코드
- 스프링 배포판을 열어보면 테스트 코드가 함께 포함되어 있음
2.5.2 학습 테스트 예제
JUnit 테스트 오브젝트 테스트
JUnit은 테스트 메소드를 수행할 때마다 새로운 오브젝트를 생성한다.
- 새로운 테스트 클래스를 작성
- 세 개의 테스트 메소드 추가
- 테스트 클래스 자신의 타입으로 스태틱 변수를 하나 선언
- 매 테스트 메소드에서 스태틱 변수에 담긴 오브젝트와 자신을 비교하여 같지 않음을 확인 후 현재 오브젝트를 스태틱 변수에 저장
public class JUnitTest {
public static JUnitTest testObject;
@Test
public void test1() {
assertThat(this, is(not(sameInstance(testObject))));
testObject = this;
}
@Test
public void test2() {
assertThat(this, is(not(sameInstance(testObject))));
testObject = this;
}
@Test
public void test3() {
assertThat(this, is(not(sameInstance(testObject))));
testObject = this;
}
}
assertThat()의 매처
- not() : 뒤에 나오는 결과를 부정
- sameInstance() : 같은 오브젝트인지 비교(동일성 비교)
문제점
- 직전 테스트에서 만들어진 테스트 오브젝트와만 비교
- 첫 번째, 세 번째 오브젝트가 같을 경우, 검증이 안 됨
해결책
- 스태틱 변수로 테스트 오브젝트를 저장할 수 있는 컬렉션을 만듦
- 현재 테스트 오브젝트가 컬렉션에 이미 등록되어 있는지 확인
- 없으면, 자기 자신을 추가
- 2~3 반복
스프링 테스트 컨텍스트 테스트
스프링 테스트 컨텍스트 프레임워크에 대한 학습 테스트
- 스프링 테스트용 애플리케이션 컨텍스트는 테스트 개수와 상관없이 한 개만 만들어짐
- 생성된 컨텍스트는 모든 테스트에서 공유됨
- 테스트용 설정파일이 필요함. applicationContext.xml이 있지만 독립적으로 만드는 것이 좋음
- 해당 설정파일에는 아무런 빈을 등록할 필요가 없음
junit.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
JUnitTest
- RunWith와 ContextConfiguration 애노테이션 추가
- Autowired로 주입된 context 변수가 같은 오브젝트인지 확인
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/junit.xml")
public class JUnitTest {
@Autowired ApplicationContext context;
static Set<JUnitTest> testObjects = new HashSet<JUnitTest>();
static ApplicationContext contextObject = null;
@Test
public void test1() {
assertThat(testObjects, not(hasItem(this)));
testObjects.add(this);
assertThat(contextObject == null | contextObject == this.context, is(true));
contextObject = this.context;
}
@Test
public void test2() {
assertThat(testObjects, not(hasItem(this)));
testObjects.add(this);
assertTrue(contextObject == null | contextObject == this.context);
contextObject = this.context;
}
@Test
public void test3() {
assertThat(testObjects, not(hasItem(this)));
testObjects.add(this);
assertTrue(contextObject == null | contextObject == this.context);
contextObject = this.context;
}
}
매번 동일한 애플리케이션 컨텍스트가 context 변수에 주입됐는지 확인
- contextObject가 null인지 확인 (첫번째 테스트인지)
- contextObject에 현재 context 저장
- 다음부터는 contextObject와 현재 context를 비교
- asserThat() : 첫 번째 파라미터에 Boolean 타입 조건문, 결과를 is() 매처와 비교
- assertTrue() : 조건문을 받아 그 결과가 true인지를 확인
- assertThat(either()) : Deprecated 됨
기타 학습 테스트를 할 수 있는 내용
- 스프링이 싱글톤 방식으로 빈의 오브젝트를 만드는 것이 사실일까?
- @Autowired로 가져온 빈 오브젝트가 어플리케이션 컨텍스트에서 직접 getBean()으로 가져온 것과 동일한가?
- XML에서 스트링 타입의 프로퍼티 값을 설정한 것이 정말 빈에 잘 주입되는가?
2.5.3 버그 테스트
버그 테스트
코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트
버그 테스트는 일단 실패하도록 만들어야하며, 버그 테스트가 성공할 수 있도록 애플리케이션 코드를 수정한다.
버그 테스트의 필요성과 장점
- 테스트의 완성도를 높여준다.
- 버그의 내용을 명확하게 분석하게 해준다.
- 기술적인 문제를 해결하는 데 도움이 된다.
테스트 기법
동등분할(Equivalence Partitioning) : 같은 결과를 내는 값의 범위를 구분해서 각 대표 값으로 테스트하는 방법
경계값 분석(Boundary Value Analysis) : 경계의 근처에 있는 값을 이용해 테스트하는 방법