단위테스트와 Junit5

·2023년 10월 30일
0

🎯개발지식

목록 보기
4/7

단위테스트와 Junit5가 무엇일까?

저의 생각으로는 개발을 하다보며 많은 클래스와 메서드가 상호작용하여 원하는 결과 값을 도출해냅니다. 여기서 만약 10개의 페이지를 지나 계산기의 더하기 기능을 만들었는데 잘 작동을 하는지 알기 위해 테스트를 가정해봅니다. 그럼 main을 실행시켜 더하기 기능까지 경로를 겪어 테스트를 해야합니다. 더하기 기능까지의 가는데 페이지가 10개를 지나가야한다며 테스트하기가 쉽지 않습니다.
그래서 main을 실행시키지 않고 해당 기능과 메서드를 테스트 할 수 있는게 단위테스트이고 해당 테스트를 도와주는게 Junit5라고 생각합니다. 그리고 직접 모든기능을 실행시켜 테스트하는 것보다 한 기능과 한 메서드씩 테스트하는 것이 더 빠르게 오류를 찾고 편리하지 않을까라는 생각을 합니다.


1. 단위테스트

단위테스트란?

하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트이다. 여기서 모듈은 애플리케이션에서 작동하는 하나의 기능 또는 메소드로 이해할 수 있다. 예를 들어 웹 애플리케이션에서 로그인 메소드에 대한 독립적인 테스트가 1개의 단위테스트가 될 수 있다.

즉, 단위 테스트는 애플리케이션을 구성하는 하나의 기능이 올바르게 동작하는지를 독립적으로 테스트하는 것으로, "어떤 기능이 실행되면 어떤 결과가 나온다" 정도로 테스트를 진행한다.

  • 응용 프로그램에서 테스트 가능한 가장 작은 소프트웨어를 실행하여 예상대로 동작하는지 확인하는 테스트
  • 단위 테스트의 테스트 대상 단위의 크기는 따로 정해져 있지는 않지만, 일반적으로 클래스 혹은 메서드 수준으로 정해진다
  • 단위의 크기가 작을 수록 단위의 복잡성이 낮아지며, 동작을 표현하기 더 쉬워진다
    → 테스트 대상 단위의 크기를 작게 설정해 단위 테스트를 최대한 간단하고 디버깅하기 쉽게 작성해야 한다

단위테스트의 필요성

  • 해당 부분만 독립적으로 테스트하기 때문에 어떤 코드를 리팩토링하여도 빠르게 문제 여부를 확인할 수 있다
  • 테스팅에 대한 시간과 비용을 절감할 수 있다.
  • 새로운 기능 추가 시에 수시로 빠르게 테스트 할 수 있다.
  • 리팩토링 시에 안정성을 확보할 수 있다.
  • 코드에 대한 문서가 될 수 있다.

좋은 단위테스트 규칙

  1. Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
  2. Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
  3. Repeatable: 어느 환경에서도 반복 가능해야 한다.
  4. Self-Validating: 테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증되어야 한다.
  5. Timely: 테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.

단위테스트 준비

  • JUnit5: 자바 단위 테스트를 위한 테스팅 프레임워크
  • AssertJ: 자바 테스트를 돕기 위해 다양한 문법을 지원하는 라이브러리

given/when/then 패턴

  • given(준비): 어떠한 데이터가 준비되었을 때
  • when(실행): 어떠한 함수를 실행하면
  • then(검증): 어떠한 결과가 나와야 한다.

2.Junit5

Junit5 어노테이션

  1. @Test

    -테스트 Method임을 선언함.

  2. @DisplayName

    -Test Class, Test Method에 사용자 정의 이름 지정
    -따로 설정하지 않으면 테스트 이름은 메소드 이름

  3. @DisplayNameGeneration

    -'_'를 공백 문자로 치환(new_test -> new test)

  4. @Disabled

    -테스트를 비활성화시켜서 테스트를 skip 할 수 있도록 한다.

  5. @BeforeEach

    -각각의 테스트 메서드 실행 이전에 매번 실행

  6. @AfterEach

    -각각 테스트 메소드 실행 이후에 실행

  7. @BeforeAll(static으로 선언)

    -현재 클래스의 모든 테스트 메서드 실행 이전에 한 번만 실행

  8. @AfterAll(static으로 선언)

    -현재 클래스의 모든 테스트 메소드 실행 이후에 한번만 실행

public class exTest {

    @BeforeEach
    public void before(){
        System.out.println("각 테스트하기 전 실행");
    }

    @AfterEach
    public void after(){
        System.out.println("각 테스트 후 실행");
    }

    @Test
    //각 테스트하기 전 실행
    public void 테스트1(){
        System.out.println("테스트1");
    }
    //각 테스트 후 실행

    @Test
    //각 테스트하기 전 실행
    public void 테스트2(){
        System.out.println("테스트2");
    }
    //각 테스트 후 실행
}



@ParameterizedTest
파라미터 값을 대입하여 검사가 필요할 경우. 반복적인 테스트문제 해결가능

  1. @ValueSource(하나의 파라미터 인수만 가능)
    -테스트를 실행하면 배열을 순회하면서, 테스트 메소드에 단일 인수로 배열에 지정된 값들을 주입해서 테스트한다. 이 때, 하나의 테스트에는 하나의 인수(argumnet)만 전달할 수 있다.
    -byte, short, int, long, float, double, char, boolean, String, Class
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int argument) {
     assertTrue(argument > 0 && argument < 4);
}
  1. @CsvSource
    -여러파라미터의 인자값 테스트 가능
    -delimiter 값을 직접 정의(delimiter 값은 String이 아닌 char 값이기 때문에 반드시 단일 문자)
@ParameterizedTest
@CsvSource(value = {"1:2", "2:4", "3:6"}, delimiter = ':')
void multiplyBy2Test(int input, int expected) {
    assertThat(multiplyBy2(input)).isEqualTo(expected);
}
  1. @NullSource
    -테스트 메소드의 파라미터 값을 null
  2. @EmptySource
    -테스트 메소드의 파라미터 값을 빈 값
  3. @NullAndEmptySourc
    -테스트 메소드의 파라미터 값에 null,빈값 모두 주입
    -@ValueSource 와 함께 사용이 가능



@RepeatedTest
-반복 횟수와 반복 테스트 이름을 설정
-RepetitionInfo 타입의 인자 사용가능
-@RepeatedTest 애노테이션 안에 value는 반복 횟수를, name은 테스트 이름

@DisplayName("반복")
@RepeatedTest(value = 10, name = "{displayName}, {currentRepetition}/{totalRepetitions}")
void repeatTest(RepetitionInfo repetitionInfo) {
    System.out.println("test " + repetitionInfo.getCurrentRepetition() + "/" +
                repetitionInfo.getTotalRepetitions());
}

참고자료

https://mangkyu.tistory.com/144
https://insight-bgh.tistory.com/507
https://velog.io/@ohzzi/junit5-parameterizedtest
https://hanseom.tistory.com/227

0개의 댓글