JUnit5 - Unit Test

Thomas·2023년 8월 3일

JUnit

자바 프로그래밍 언어용 유닛 테스트 프레임워크.

유닛 테스트(단위 테스트)

애플리케이션을 구성하는 하나의 기능이 올바르게 동작하는지를 독립적으로 테스트하는 것

JUnit 사용이유

개발하면서 기능의 개발 및 기능의 변경이 있을 떄마다 서버구동을 하여 일일이 확인하는 불필요한 작업을 수행하거나 수정한 기능을 올리면서 장애가 날까 불안해 하지 않도록 도와준다.

JUnit5

아래의 그림을 좀더 자세하게 살펴보자

  • JUnit platform
    * JVM에서 동작하는 테스트 프레임워크
    • TestEngine 인터페이스를 정의한다
    • TestEngine을 통해 테스트를 발견하고, 실행하고, 결과를 보고한다.
  • JUnit Jupiter
    * TestEngine 구현체
    • Jupiter API(JUnit5를 위한 테스트 API)를 사용해 작성한 테스트 코드를 실행할 떄 사용
  • JUnit Vintage
    * TestEngine 구현체
    • 기존 JUnit3,4 버전으로 작성한 테스트 코드를 실행할 떄 사용

JUnit 5 설정하기

자바 8 이상 스프링부트 2.1 이상부터 사용이 가능하다.
기본적으로 JUnit5 의존성이 추가된다

dependencies {
	testImplementation'org.junit.jupiter:junit-jupiter-api:5.8.2' 
	testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}

의존성 추가해주면 된다.

JUnit5 Annotation

@Test

테스트의 시작을 알리는 어노테이션

@DisplayName

@DisplayName("테스트의 메소드를 나타낸다 ")

@BeforeEach

각각의 테스트 메서드가 실행되기 전 특정 작업을 수행해야 할 떄 사용한다.
주로 테스트에 필요한 목업 데이터를 미리 세팅해주는 용도로 사용된다

@AfterEach

각각의 테스트 메서드가 실행된 후 특정 작업을 수행해야 할 때 사용한다.

@BeforeAll, @AfterAll

한 클래스의 모든 메서드가 실행 되기 전 / 후 특정 작업을 수행해야할 떄 사용한다.
-> Static 사용 필수

Junit 생명주기

개별 테스트의 독립성을 보장하고, 테스트 사이의 상호관계에서 발생하는 부작용을 방지하기 위해, Junit는 테스트 메소드의 실행 전 각각 새로운 인스턴스를 생성한다.
-> 이를 통해 개별 테스트 메서드는 완전히 독립적인 객체 환경에서 동작하며, 이를 메서드 단위 생명주기라고 한다.

@BeforeAll

해당 클래스에 위치한 모든 테스트 메서드 실행 전에 딱 한 번 실행되는 메서드

@AfterAll

해당 클래스에 위치한 모든 테스트 메서드 실행 후에 딱 한 번 실행되는 메서드

@BeforeAll,@AfterAll: Static 사용 필수

non-static을 사용하고 싶으면 아래의 @TestInstance를 사용하면 된다

@BeforeAll Vs @BeforeEach

@BeforeAll: 테스트가 이 조건들에 대해 어떠한 변경도 하지 않을 때 사용
@BeforeEach: 테스트가 조건들에 영향을 미칠 때 사용
-> 조건떄마다 초기화할 수 있도록 BeforeEach 사용해주는게 좋음

@TestInstance

하나의 인스턴스를 공유 할려면 @TestInstance를 쓴다

@TestInstance(TestInstance.Lifecycle.PER_CLAS)
public class CountTest {
	int count = 1;
	@Test
    void countTest1() {
    	System.out.println(this);
        System.out.println(count++);
    }
    @Test
    void countTest2() {
    	System.out.println(this);
        System.out.println(count++);
    }
 }

-> 결과값은 1,2 가 나오는것을 알 수 있다.

@ParameterizedTest

단독으로 사용되진 않고 어떤 파라미터를 사용하는지에 관한 어노테이션을 추가로 선언
즉, 테스트에 여러 다른 매개변수를 대입해가며 반복 실행할 떄 사용
-> 반복문을 사용하는 것보다 가독성이 향상되고 테스트의 성격이나 목적 등을 잘 드러낼수 있다.

@NullSource, @EmptySource

@ParameterizedTest이랑 같이 쓰는 어노테이션이다.

@ParameterizedTest
@NullSource
@EmptySource
void nullEmptyStrings(String text) {
	assertTrue(text == null || text.trim().isEmpty());
}

@ValueSource

반복적인 테스트를 진행할 때 사용하는 어노테이션이다.

@ParameterizedTest
@ValueSource(strings = {"a", "b"})
public void test(String string) {
	System.out.println(string);
}

@ParameterizedTest
@ValueSource(ints = {1,2,3,4,5})
public void test1(Integer integer) {
	System.out.println(integer);
}


여러가지 타입으로 사용이 가능하다.

@CsvSource

입력값과 예상 값을 전달하여 테스트가 반복될 떄마다 @CsvSource에서 하나의 배열 항목을 가져와 쉼표로 분할하고 각 배열을 매개변수로 전달한다.

@Nested

  • 테스트 클래스 안에서 내부 클래스를 정의해 테스트를 계층화 할 떄 사용
  • 내부클래스는 부모클래스의 맴버 필드에 접근가능
  • Before / After와 같은 테스트 생명주기에 관계된 메소드들도 계층에 맞춰 동작

@RepeatedTest

Value 횟수만큼 반복적으로 실행된다

@RepeatedTest(3)
void test() {
	System.out.println("test");
}

여기선 3이라서 3번 실행된다.

성능적인 이슈를 확인할 때 사용하면 좋음

@Disabled

테스트를 하고 싶지 않은 클래스나 메서드에 붙이는 어노테이션

JUnit Assertions

Junit5는 다양한 assertion 기능을 제공한다. assertion은 테스트에서 예상한 결과와 실제 결과를 비교하여 검증하는 기능이다.

  • assertEquals(expected, actual);
  • assertNotEquals(unexpected,actual);
  • assertSame(Object expected, Object actual)
  • assertNotSame(Object unexpected, Object actual)
  • assertTrue(boolean condition)
  • assertFalse(boolean condition)
  • assertNull(Object actual)
  • assertNotNull(Object actual)
  • fail() : 테스트를 실패 처리한다.
  • assertAll(executables...) : 매개변수로 받는 모든 테스트코드를 한 번에 실행(오류가 나도 끝까지 실행)
assertAll(
	() -> assertEquals...
    () -> assertNotNul...
);
  • assertThrows(epectedType, executable) : 예외의 내부 상태를 검증 할 수 있는 기능
    -> 예외를 발생 시키고 예외를 반환 받아서 예외의 상태까지 검증할 수 있다.
  • assertDoesNotThorow(executable) :예외가 던져지지 않음을 검증

참고자료:
https://junit.org/junit5/docs/current/user-guide/
https://www.youtube.com/watch?v=uqZDt-0BDAo&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC
https://www.youtube.com/watch?v=EwI3E9Natcw&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC

profile
Backend Programmer

1개의 댓글

comment-user-thumbnail
2023년 8월 3일

즐겁게 읽었습니다. 유용한 정보 감사합니다.

답글 달기