본문 바로가기

Spring/토비의 스프링 3.1

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


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

학습 테스트
자신이 만들지 않은 프레임워크나 다른 개발팀에서 만들어서 제공한 라이브러리 등에 대해서 작성한 테스트

학습 테스트의 목적

  • 사용할 API나 프레임워크의 기능을 테스트로 보면서 사용 방법을 익히기 위함
  • 자신이 테스트를 만들려고 하는 기술이나 기능에 대해 얼마나 제대로 알고 있는 지를 검증
  • 빠르고 정확하게 사용법을 익히기 위함

테스트 대상보다 테스트 코드 자체에 관심을 가져야 함

2.5.1 학습 테스트의 장점

  1. 다양한 조건에 따른 기능을 손쉽게 확인 가능
    • 자동화된 테스트 코드로 만들어지기 때문에 다양한 조건에 따라 기능이 어떻게 동작하는지 빠르게 확인이 가능
  2. 학습 테스트 코드를 개발 중 참고 가능
    • 예제를 만드는 방법의 경우 최종 수정 예제만 남게 된다.
    • 학습 테스트는 코드를 개별적으로 만들고 남겨둘 수 있으므로 개발 중 좋은 참고 자료가 된다.
  3. 프레임워크 또는 제품 업그레이드 시 호환성 검증을 도와줌
    • 기존에 사용하던 API가 기능에 문제가 없다는 사실을 미리 확인해 볼 수 있음.
    • 기능에 변화가 있거나 업데이트 된 제품에 버그가 있다면, 미리 확인할 수 있음
    • 사용법에 변화가 생긴 경우 그에 맞춰 애플리케이션 코드를 수정할 계획을 세울 수 있음
  4. 테스트 작성에 좋은 훈련이 된다.
    • 테스트 코드 작성을 연습할 수 있다,
    • 학습 테스트의 경우 한두 가지 간단한 기능에만 초점을 맞추면 되기 때문에 테스트도 대체로 단순하다.
  5. 새로운 기술을 공부하는 과정이 즐거워진다.

스프링 학습 테스트 시 참고할 수 있는 가장 좋은 소스 : 스프링 자신에 대한 테스트 코드

  • 스프링 배포판을 열어보면 테스트 코드가 함께 포함되어 있음

2.5.2 학습 테스트 예제

JUnit 테스트 오브젝트 테스트

JUnit은 테스트 메소드를 수행할 때마다 새로운 오브젝트를 생성한다.

  1. 새로운 테스트 클래스를 작성
  2. 세 개의 테스트 메소드 추가
  3. 테스트 클래스 자신의 타입으로 스태틱 변수를 하나 선언
  4. 매 테스트 메소드에서 스태틱 변수에 담긴 오브젝트와 자신을 비교하여 같지 않음을 확인 후 현재 오브젝트를 스태틱 변수에 저장
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() : 같은 오브젝트인지 비교(동일성 비교)

문제점

  • 직전 테스트에서 만들어진 테스트 오브젝트와만 비교
  • 첫 번째, 세 번째 오브젝트가 같을 경우, 검증이 안 됨

해결책

  1. 스태틱 변수로 테스트 오브젝트를 저장할 수 있는 컬렉션을 만듦
  2. 현재 테스트 오브젝트가 컬렉션에 이미 등록되어 있는지 확인
  3. 없으면, 자기 자신을 추가
  4. 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 변수에 주입됐는지 확인

  1. contextObject가 null인지 확인 (첫번째 테스트인지)
  2. contextObject에 현재 context 저장
  3. 다음부터는 contextObject와 현재 context를 비교
    • asserThat() : 첫 번째 파라미터에 Boolean 타입 조건문, 결과를 is() 매처와 비교
    • assertTrue() : 조건문을 받아 그 결과가 true인지를 확인
    • assertThat(either()) : Deprecated 됨

기타 학습 테스트를 할 수 있는 내용

  • 스프링이 싱글톤 방식으로 빈의 오브젝트를 만드는 것이 사실일까?
  • @Autowired로 가져온 빈 오브젝트가 어플리케이션 컨텍스트에서 직접 getBean()으로 가져온 것과 동일한가?
  • XML에서 스트링 타입의 프로퍼티 값을 설정한 것이 정말 빈에 잘 주입되는가?

2.5.3 버그 테스트

버그 테스트
코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트
버그 테스트는 일단 실패하도록 만들어야하며, 버그 테스트가 성공할 수 있도록 애플리케이션 코드를 수정한다.

버그 테스트의 필요성과 장점

  1. 테스트의 완성도를 높여준다.
  2. 버그의 내용을 명확하게 분석하게 해준다.
  3. 기술적인 문제를 해결하는 데 도움이 된다.

테스트 기법
동등분할(Equivalence Partitioning) : 같은 결과를 내는 값의 범위를 구분해서 각 대표 값으로 테스트하는 방법
경계값 분석(Boundary Value Analysis) : 경계의 근처에 있는 값을 이용해 테스트하는 방법


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

3.0 템플릿  (0) 2019.01.17
2.6 정리  (0) 2019.01.17
2.4 스프링 테스트 적용  (0) 2019.01.17
2.3 개발자를 위한 테스팅 프레임워크 JUnit  (0) 2019.01.14
2.2 UserDaoTest 개선  (0) 2019.01.11