1-2 테스트

Reading-Snail·2023년 12월 5일
1

DI 다음으로 스프링에서 가장 강조하고 있는 개념은 테스트입니다. 테스트는 개발자로 하여 안정감을 갖을 수 있게 해줍니다. JUnit과 TDD 개념에서 언급 되듯이 코드를 수정했지만 발 뻗고 잘 수 있는 안정감 말입니다.

단위 테스트

하나의 프로그램 전체를 테스트하기란 사실상 불가 합니다. 왜냐하면 기능들이 상호 간 연관되어 있기에 모든 기능이 다 구현되었을 때야 비로소 테스트가 가능하기 때문입니다. 그래서 테스트는 기본적으로 기능 단위로 쪼개서 테스트하는 단위 테스트가 기본이 됩니다.

스프링에서의 테스트가 추구하는 바도 동일합니다. JUnit 프레임워크와 TDD에서 강조되는 것과 같이 스프링에서도 단위 테스트를 중심으로 하여 개발하도록 권장하고 있습니다.

단언/검증

일반적인 테스트에서는 로그를 찍는 방식으로 테스트할 것입니다. System.out.println()과 같은 메서드를 사용하게 되는데 JUnit과 스프링에서는 단언/검증이라고 불리는 방법을 사용하게 됩니다. assertThat()과 같은 메서드는 기대값과 결과값을 비교하여 테스트의 성공과 실패를 알려줍니다. 또한, 실패하더라도 결과값 등 여러 데이터를 제공하여 개발자로하여 코드를 수정할 수 있도록 돕습니다. 이러한 성공과 실패로 결과를 내는 방식은 테스트를 자동화 시키는 것을 돕습니다. 여러 개의 테스트를 실행해도 어떤 테스트가 실패한 테스트를 가려내는 것을 도와줍니다.

JUnit 과 특징

스프링의 내장된 테스트는 JUnit에 뿌리를 둡니다.
테스트 코드는 몇가지 특징을 갖는데 아래와 같습니다.

  • 메서드가 public이여야 합니다
  • @Test 애노테이션으로 테스트 코드임을 알립니다.
  • assertThat() 으로 검증 합니다.

테스트의 일관성

테스트는 항상 동일한 코드에서 동일한 결과를 만들어내야 합니다. 이를 위협할 수 있는 대표적인 예시가 데이터베이스와 상호 작용하게 되는 부분 입니다. 이러한 오류를 막기 위해서는 테스트 실행 후 입력된 데이터를 초기화하거나 롤백하여 데이터에 변경이 없을 수 있도록 유도해야 합니다. 또는 목 오브젝트를 사용하여 데이터베이스를 직접 사용하지 않도록 하는 것도 좋습니다. 이는 서비스 추상화에서 다시 언급됩니다.

예외 테스트

결과 값 뿐만 아니라 발생할 것으로 기대되는 예외도 테스트 할 수 있습니다. 예를 들어, @Test(Expected=exception.class) 와 같은 구문을 사용하여 발생될 것으로 기대되는 예외가 발생하였을 때만 성공이라는 피드백을 받을 수 있도록 할 수 있습니다.

TDD(테스트 주도 개발)

테스트 코드를 먼저 만든 후 코드를 만들어나가는 방법입니다. 항상 테스트는

  • 조건: 어떤 조건을 가지고
  • 행위: 무엇을 할 때
  • 결과: 어떤 결과가 나온다
    라는 접근을 가지고 있어야 합니다. 구현이 되기전에 테스트는 당연히 실패합니다. 실패한 코드를 성공으로 테스트를 실패로 시작해서 성공으로 끝났을 때 코드의 구현도 끝나는 것입니다.

JUnit의 로직

  1. @Test, public, void, 파라미터 없는 메서드 탐색
  2. 테스트 클래스의 오브젝트 생성
  3. @Before 수행
  4. @Test 수행
  5. @After 수행
  6. 모든 테스트 메서드를 @Before->@Test->@After순으로 수행
  7. 종합 결과를 반환
    Fixture: 테스트에서 필요한 정보

테스트 ApplicationContext

@RunWith(SpringJUnit4ClassRunner.class): 어떤 테스트 프레임워크를 사용할지 선택
@ContextConfig(locations=“/application.xml”) 테스트에 사용할 어플리케이션 컨텍스트 설정 정보
@Autowired: DI를 통해 객체 주입
스프링의 객체를 컨텍스트에서 관리하므로 매번 객체를 생성할 필요가 없어 테스트 시간을 줄여줍니다.

런타임 도중 스프링 컨테이너 조작

@DirtiesContext를 사용하면 테스트 도중에 스프링 컨테이너에 조작을 가할 수 있다. 그러나 권장되는 방법은 아닙니다.

당연히 Autowired와 같은 DI를 필수로 사용하지 않아도 된다. 생성자를 사용해서 컨테이너 없이 객체를 생성하는 것도 당연히 가능합니다.

테스트 방법 선택

  1. 스프링 컨테이너 없이 테스트 할 수 있는 방법을 먼저 고민해야 됩니다. 빠르고, 단순하다.
  2. 여러 오브젝트를 불러와야 할 경우 DI를 사용하면 편리하다. 테스트 어플리케이션 컨텍스트를 사용하단다면 별도의 Configuration을 만들어 관리해도 좋습니다.
  3. 예외적이 의존관계가 필요할 경우 DI 받아온 오브젝트에 new로 생성한 오브젝트를 다시 주입하는 방식을 사용할 수 있다. 이때는 @DirtiesContext를 붙여야 합니다.

학습 테스트

자신이 작성하지 않은 코드들에 대해서 테스트를 추가하고, 이해도를 높이는 학습 방법입니다.
1. 다양한 조건들에 따라 어떻게 동작하는지 알 수 있습니다.
2. 개발 도중에 참고할 수 있습니다
3. 업그레이드 시 호환성 테스트를 도와줍니다.
4. 테스트 코드 작성 훈련을 할 수 있습니다.

버그테스트

버그로 인해 실패하는 테스트를 먼저 작성한 후 이를 성공할 수 있게 변경하는 방법의 테스트 방법입니다.
1. 불충분 했던 테스트를 추가하여 완성도를 높입니다.
2. 버그 내용을 완벽하게 분석해준다.
3. 기술적인 부족을 해결하는 데 도움을 줍니다.

"토비의 스프링 3.1" - 이일민

profile
책읽는 달팽이 || 공학도에서 개발자로! || 결국 과거의 흐름을 이해했을 때 지금의 것들을 통찰력있게 바라볼 수 있다고 믿습니다.

0개의 댓글

관련 채용 정보