SEB_BE 54일차 - 테스팅1

subimm_·2022년 11월 9일
0

코드스테이츠

목록 보기
54/83

💡 오늘의 학습목표

  • 단위 테스트
  • JUnit을 사용한 단위 테스트
  • Hamcrest를 사용한 Assertion

📔 단위 테스트 (Unit Test)

  • 애플리케이션의 일반적인 테스트 분류

  • 기능 테스트
    애플리케이션을 사용하는 사용자 입장에서 애플리 케이션이 제공하는 기능이 올바르게 동작하는지
    일반적으로 QA가 테스트 (단위 테스트로 부르기는 힘들다)

  • 통합 테스트
    애플리케이션을 만든 개발자 또는 개발팀이 테스트의 주체가 됨
    (단위 테스트라고 할 순 없음)

  • 슬라이스 테스트
    애플리케이션을 특정 계층으로 쪼개어서 하는 테스트

  • Mokc(가짜) 객체를 사용해서 계층별로 끊어서 테스트 (단위 테스트라고 하기엔 단위가 크며, 부분 통합 테스트라고 부르기도 한다)

  • 단위 테스트
    비즈니스 로직에서 사용하는 클래스들이 독립적으로 테스트하기 가장 좋은 대상
    단위 테스트 코드는 메서드 단위로 대부분 작성된다.

    • 테스트 케이스 (Test Case) 란?
      테스트를 위한 입력 데이터, 실행 조건, 기대 결과를 표현하기 위한 명세
      메서드 등 하나의 단위를 테스트하기 위해 작성하는 테스트 코드

📖 단위 테스트를 위한 F.I.R.S.T 원칙

  • Fast(빠르게)
    일반적으로 작성한 테스트 케이스는 빨라야 한다.
  • Independent(독립적)
    각각의 테스트 케이스는 독립적이어야 한다.
    클래스 내의 메서드 여러 개 테스트 시 어떤 테스트 케이스를 먼저 실행시켜도 실행되는 순서와 상관없이 정상적인 실행이 보장되어야함.
  • Repeatable(반복 가능하도록)
    어떤 환경에서도 반복해서 실행이 가능해야 한다.
    (테스트 시 외부의 리소스나 서비스 연동을 끊어주는 것이 바람직)
  • Selfvalidating(셀프 검증이 되도록)
    테스트 케이스 스스로 결과가 옳은지 그른지 판단할 수 있어야 한다.
  • Timely(시기 적절하게)
    테스트 하려는 기능 구현을 하기 직전에 작성해야 한다.
    구현하고자 하는 기능을 단계적으로 조금씩 업그레이드 하면서, 그때 그때 테스트 케이스 역시 단계적으로 업그레이드 하는 방식이 더 낫다.

📜 JUnit 없이 비즈니스 로직에 단위 테스트 적용해보기

  • 테스트 대상 헬퍼 클래스
  • 테스트 케이스

    Given-When-Then 표현 스타일
  • BDD(Behavior DrivenDevelopment) 라는 테스트 방식에서 사용하는 용어
  • Given
    • 테스트를 위한 준비 과정을 명시할 수 있다.
    • 테스트에 필요한 전제 조건들이 포함된다고 보면됨.
    • 테스트 대상에 전달되는 입력 값(테스트 데이터) 역시 Given에 포함
  • When
    • 테스트 할 동작(대상)을 지정
    • 단위 테스트에서는 일반적으로 메서드 호출을 통해 테스트를 진행하므로 한 두줄 정도로 끝남.
  • Then
    • 테스트의 결과를 검증하는 영역
    • 일반적으로 예상하는 값(expected)과 테스트 대상 메서드의 동작 수행 결과(actual) 값을 비교해서 기대한대로 동작을 수행하는지 검증(Assertion) 하는 코드들이 포함됨.
  • Assertion(단언문, 단정문) 이란?
    테스트 결과를 검증할 때 주로 사용 (예상하는 결과값이 참이길 바라는 것)
  • 테스트 대상 헬퍼 테스트(추가)
  • (1) 회원이 주문한 주문 정보에서 얻게되는 스탬프 개수를 계산하는 기능
  • 테스트 케이스
  • calculateEarnedStampCount() 메서드를 테스트하는 테스트 케이스
  • given
    • 주문한 커피의 수량이 필요하기 때문에 Order와 OrderCoffee 객체를 직접 만들어서 테스트에 필요한 데이터 생성
  • when
    • 테스트 대상인 StampCalculator.calculateEarnedStampCount()에 given에서 생성한 테스트 데이터를 입력값으로 전달
  • then
    • 주문한 커피 수량 만큼의 스탬프가 계산되는지를 Assertion 한다.

📔 JUnit으로 비즈니스 로직에 단위 테스트 적용하기

📖 JUnit 이란?

  • Java언어로 만들어진 애플리케이션을 테스트 하기 위한 오픈 소스 테스트 프레임워크로서 사실상 Java의 표준 테스트 프레임 워크 (Spring Boot의 디폴트 테스트 프레임워크)
  • 현재 Junit 5

JUnit 기본 작성법

  • Spring Boot Initializr에서 Gradle 기반의 Spring Boot 프로젝트 생성 후 오픈하면 기본적으로 src/test 디렉토리가 생성됨. 기본적으로 스타터 포함 JUnit도 포함되어 있음.

✔ JUnit을 사용한 테스트 케이스의 기본 구조

  • 애플리케이션에서 테스트하고자 하는 대상(Target)이 있으면 public void test(){..} 같은 메서드를 만들고 @Test 애너테이션 추가

Assertion 메서드 사용하기

  • assertEquals()
  • assertEquals() 메서드를 사용하면 기대하는 값과 실제 결과 값이 같은지 검증 가능
    (1)은 테스트 케이스를 실행시켰을 때, 실행 결과 창에 표시되는 이름을 지정하는 부분
  • 테스트 케이스 성공 ( 초록색 체크 아이콘 )

  • 테스트 케이스 실패


  • assertNotNull() : Null 여부 테스트

  • (1)에서 assertNotNull() 메서드를 사용하면 테스트 대상 객체가 null이 아닌지 테스트 가능
    메서드의 첫번 째 파라미터는 테스트 대상 객체, 두번째 파라미터는 테스트 실패 시 표시할 메세지

  • 실행 결과는 "ETH"에 해당하는 암호 화폐 이름이 map에 저장되있기 때문에 "passed"

  • assertThrows() : 예외(Exception) 테스트

  • getCryptoCurrency() 메서드를 호출 시 , NullPointerException이 발생하는지 테스트

  • (1)에서 assertThrows()의 첫 번째 파라미터에는 발생이 기대되는 예외 클래스, 두번 째 파라미터인 람다 표현식에서는 테스트 대상 메서드를 호출

  • XRP에 해당하는 암호화폐는 map에 존재하지 않기 때문에 map 에서 반환된 값은 null
    null값 상태에서 대문자 변환시도하여 예외 발생, 실행 결과 passed

    • 예외 타입이 다를 경우?
      아예 다른 타입이라면 테스트 실행 결과는 failed ,
      널예외 대신 런타임예외 또는 상위 예외 타입으로 바꾸면 passed
      • 예외 클래스의 상속 관계를 이해해야함.
  • Executable 함수형 인터페이스
    assertThrows()의 두번째 파라미터인 람다 표현식은 JUnit에서 지원하는 Excutable 함수형 인터페이스
    • void execute() throws Throwcle;메서드 하나만 정의되어 있고 리턴값이 없다.
      리턴값이 없는 Consumer에 해당

테스트 케이스 실행 전, 전처리
테스트 케이스를 실행하기 전 어떤 객체나 값에 대한 초기화 작업 등의 전처리 과정 해야할 경우

  • @BeforeEach
  • 실행결과
  • init() 메서드가 총 두번 실행됨.
    @BeforeEach 애너테이션을 추가한 메서드는 테스트 케이스가 각각 실행될 때마다 테스트 케이스 실행 직전에 실행되어 초기화 작업 진행 가능
  • Test case 2는 failed, Test case 1은 passed
  • assertDoesNotThrow() 메서드는 예외가 발생하지 않는다고 기대하는 Assertion 메서드
  • Test case1은 어썰션하기 전에 map에 XRP 값 추가하여 통과
  • Test case2는 어썰션하기 전에 init()메서드로 다시 초기화되어 XRP 값이 없어서 실패함.

  • @BeforeAll()
    클래스 레벨에서 테스트 케이스를 한꺼번에 실행시키면 테스트 케이스가 실행되기 전 딱 한번만 초기화 작업을 해줌.
  • @BeforeAll 애너테이션을 추가한 메서드는 정적 메서드(static method) 여야함.

✔ 테스트 케이스 실행 후 , 후처리

  • @AfterEach , @AfterAll before와 동작 방식은 같고 호출되는 시점만 반대

✔ Assumption을 이용한 조건부 테스트
~라고 가정하고 의 '가정' 에 해당
특정 환경에만 테스트 케이스가 실행되도록 할 수 있다.

  • (1) assumeTrue() 메서드는 파라미터로 입력된 값이 true이면 나머지 아래 로직 실행
    운영체제가 윈도우즈라면 실행
  • assumeTrue() 메서드는 OS환경 등의 특정 조건에서 선택적인 테스트가 필요할시 유용하다.
profile
코린이의 공부 일지

0개의 댓글