테스트 관련 이론 정리

김윤서·2024년 9월 10일
0

테스트를 작성하는 이유?

  • 디버깅 감소
    • 테스트를 한 번 작성해두면 프로젝트가 살아 있는 내내 값비싼 결함을 예방해주고, 짜증 나는 디버깅에서 해방시켜준다.
  • 자신 있는 변경
    • 좋은 테스트로 무장한 프로젝트는 자신감을 갖고 변경하고 리팩토링 할 수 있다.
  • 더 나은 문서자료
    • 하나의 행위만 집중해 검증하는 명확한 테스트는 마치 실행 가능한 문서와 같다.
  • 더 단순한 리뷰
    • 리뷰어가 변경된 코드가 제대로 작동하는지 검증하는 시간을 줄여준다.
  • 사려 깊은 설계
    • 새로 작성한 코드의 테스트를 작성하는 일은 실질적으로 해당 코드의 API가 잘 설계되었는지를 시험하는 행위이다.
  • 고품질의 릴리스를 빠르게
    • 건실한 자동 테스트 스위트를 갖춘 팀은 새로운 버전을 릴리즈하며 불안에 떨지 않는다.

단위 테스트와 통합 테스트

  • 단위 테스트 : 가장 작은 단위의 테스트 방식. 메서드 단위로 테스트를 수행하고, 의도한 결과값이 나오는지 확인하는 수준 (ex: controller, service, repository… 격리해서 따로따로)
  • 통합 테스트 : 어플리케이션이 정상적으로 동작하는지 확인. 여러모듈을 함께 테스트 (ex: controller 메소드를 호출하면 controller → service→ repository 모두 수행)

TDD (Test Driven Development)

  • 개발 할 때 테스트 코드를 먼저 작성하고 해당 테스트를 성공 시키게 만들면서 리팩토링 하는 개발 기법
    • 순서
      • 원하는 행위를 먼저 테스트 코드에 작성한다. → 실제 코드가 없기에 당연히 실패함
      • 실제 코드를 원하는 행위를 할 수 있게 코드를 작성함 → 개발이 완료되면 테스트 코드가 성공
      • 2번에서 작성한 코드를 가독성 및 유지보수가 쉽도록 리팩토링
      • 리팩토링 완료 후 테스트 실행하여 성공 여부 확인

💡 좋은 테스트를 위한 F.I.R.S.T 원칙

  • Fast : 단위 테스트는 빨라야 한다. (가장 중요~)
  • Independent : 단위 테스트는 각각의 테스트가 연관되지 않고, 고립되어야 한다. 즉 독립적
    이어야 한다.
  • Repeatable : 단위테스트는 반복 가능해야한다. 반복적으로 시행해도 결과는 같아야 한다.
  • Self-validating : 자체적으로 테스트 결과가 도출되야한다. (개발자가 print 찍어서 비교하는게 아니고 자동으로 수행되며 성공/실패 의 결과가 나오는 것)
  • Timely : 단위 테스트는 실제 코드보다 먼저 구현해야한다. (TDD일 경우에만 해당)

💡 Test 실행을 위한 Given-When-Then 패턴

  • Given : 테스트에 필요한 변수를 정의하거나 Mock 객체를 통해 특정 상황 또는 행동을 정의합니다.
  • When: 실제 테스트를 하는 메소드가 호출되며 테스트를 통한 결과값을 가져옵니다.
  • Then: When 단계에서 나온 결과값을 검증하는 작업을 수행합니다.

JUnit + Mockito

  • JUnit : Java 에서 사용되는 대표적인 테스트 프레임워크. 자바 개발자 93% 가 사용한다는 통계가 있습니다. Assertion을 이용하여 예상하는 값과 실제 도출된 값을 검증할 수 있는 기능을 지원합니다.
  • Mockito : Mock 객체를 쉽게 만들고, 관리하고, 검증할 수 있는 방법을 제공하는 프레임워크 입니다. Mock 객체는 진짜 객체와 비슷하게 동작하지만 프로그래머가 직접 행동을 관리하는 객체입니다.

💡 Mockito에서 Mock(가짜) 객체의 의존성 주입을 위해서는 크게 3가지 어노테이션이 사용됩니다.

  • @Mock: Mock 객체를 만들어 반환해주는 어노테이션
  • @Spy: Stub하지 않은 메소드들은 원본 메소드 그대로 사용하는 어노테이션
  • @InjectMocks: @Mock 또는 @Spy로 생성된 가짜 객체를 자동으로 주입시켜주는 어노테이션
  • @MockBean: 기존에 사용되던 Bean의 껍데기만 가져오고 내부의 구현 부분은 모두 사용자에게 위임 (Spring 에 자동으로 Bean 으로 주입됨)
  • @SpyBean: given에서 선언한 코드 외에는 전부 실제 객체의 것을 사용합니다.
    - @MockBean은 given에서 선언한 코드 외에는 전부 사용할 수 없습니다.
    예를 들어 UserController에 대한 단위 테스트를 작성하고자 할 때, UserService를 사용하고 있다면 @Mock 어노테이션을 통해 가짜 UserService를 만들고, @InjectMocks를 통해 UserController에 이를 주입시킬 수 있습니다.

0개의 댓글