JUnit5 사용법

지능바바·2023년 6월 4일
0

JUnit

목록 보기
1/2

1. JUnit 이란?

자바를 테스트하기 위한 Framework이다. 이 포스트를 작성하는 현재 JUnit의 최신버전은 5버전이다.
JUnit5는 아래의 3개의 모듈로 구성되어있다.

JUnit Platform : JUnit의 핵심 모듈로서 테스트 프레임워크를 구동하기 위한 런처와 테스트 엔진을 위한 API를 제공.
JUnit Jupiter : JUnit5를 위한 테스트 API와 실행 엔진을 제공.
JUnit Vintage : 이전 버전의 JUnit으로 작성된 테스트를 JUnit5에서 실행하기 위한 모듈 제공.

2. JUnit 의존성 주입

스프링부트에서의 의존성 주입

dependencies {
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

스프링 이외의 환경에서의 의존성 주입

dependencies {
	testImplementation('org.junit.jupiter:junit-jupiter-api:5.9.3') {
    	exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

JUnit3 또는 JUnit4 로 작성된 코드가 있을경우 exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 부분은 제거한다.

2. 기본 어노테이션

  • @Test : 테스트로 지정한다.
  • @BeforeAll : 테스트가 실행되기전에 단 한번만 실행된다. 테스트 인스턴스의 라이프 사이클이 PER_METHOD 인 경우 static 메소드에만 지정 가능하다.
  • @AfterAll : 테스트가 실행된 후 단 한번만 실행된다. 테스트 인스턴스의 라이프 사이클이 PER_METHOD 인 경우 static 메소드에만 지정 가능하다.
  • @BeforeEach : 각 테스트가 실행되기전에 매번 실행된다.
  • @AfterEach : 각 테스트가 실행된 후 매번 실행된다.
  • @Disabled : 사용하지 않는 테스트로 지정하여 테스트를 실행시키지 않는다.
  • @DisplayName : 테스트의 이름을 지정할 수 있다.

3. 테스트 인스턴스

JUnit은 기본적으로 @Test 어노테이션이 붙은 메소드마다 하나의 인스턴스로 생성되어 테스트가 실행된다. 그러므로 테스트가 서로 영향을 미치지 않게 되어있다. 하지만 테스트코드를 만들다보면 다른 테스트의 결과를 기반으로 테스트를 진행할 필요가 있는 경우가 있다. 예를 들어 아래와 같은 경우이다.

  • 등록 > 조회 > 수정 > 삭제

위의 4가지를 테스트 할 때마다 매번 새로운 데이터를 등록하는것은 번거로운 일이 될 것이다.
이 때 테스트 인스턴스의 범위를 수정하여 각 테스트가 서로 영향을 주도록 변경할 수 있다.

@TestInstance 어노테이션을 Test Class에 지정함으로서 테스트의 라이프 사이클을 조정가능하다.

@TestInstance(TestInstance.Lifecycle.PER_METHOD)

위와 같이 LifeCycle.PER_CLASS로 @TestInstance를 설정해 주게 되면 @Test 어노테이션이 붙은 메소드마다 생성되던 인스턴스가 각각의 테스트 클래스별로 생성되게 된다. 그러므로 클래스마다 테스트중에 변경된 사항을 서로 공유가 가능하다.

4. 테스트 순서 지정

테스트 인스턴스를 통해서 각각의 테스트가 서로 영향을 줄 수 있도록 지정하는 방법을 알아보았다. 그런데 각 테스트는 서로 실행되는 순서를 보장하지 않는다. 그러므로 테스트가 등록 > 조회 > 수정 > 삭제 순으로 실행된다는 보장이 없다. 이 때 이 순서를 지정하는 방법은 아래와 같다.

  1. 테스트 클래스에 @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 어노테이션을 지정한다.
  2. 각각의 테스트 메소드에 @Order 어노테이션을 통해 순서를 지정한다.

아래의 코드와 같이 @Order를 통해서 테스트의 순서를 지정할 수 있다. @Order 에 설정된 값이 작을수록 우선순위가 높으며 파라미터는 int이기 때문에 음수도 가능하다.

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ServiceTest {

    @Order(1)
    @Test
    void test1() {
        System.out.println(1);
    }

    @Order(2)
    @Test
    void test2() {
        System.out.println(2);
    }

    @Order(3)
    @Test
    void test3() {
        System.out.println(3);
    }

    @Order(4)
    @Test
    void test4() {
        System.out.println(4);
    }
}

5. 반복적인 테스트

@RepeatedTest

정해진 횟수만큼의 테스트를 반복한다. RepetitionInfo 객체를 통해 반복횟수에 대한 정보를 가져올 수 있다.

@RepeatedTest(3)
void insert(RepetitionInfo info) {
    System.out.println(info.getCurrentRepetition() + "/" + info.getTotalRepetitions());
}

@ParameterizedTest

하나의 테스트에 다른 파라미터를 넘기면서 여러번 테스트를 진행할 수 있도록 해주는 기능이다.
@MethodSource, @ArgumentSource, @CvsSource, @ValueSource, @NullSource, @EmptySource 등등의 기능을 통해서 다양한 방식으로 파라미터를 전달하여 사용할 수 있다.
여기서는 @MethodSource를 이용해서 파라미터를 넘기는 방법을 예제로 작성했다.

@ParameterizedTest
@MethodSource("fixtureForTest1")
void test1(String name, int index, String expected) {
    String actual = name + index;
    Assertions.assertEquals(actual, value);
}

static List<Arguments> fixtureForTest1() {
    return List.of(
            Arguments.arguments("테스트", 0, "테스트0"),
            Arguments.arguments("테스트", 1, "테스트1"),
            Arguments.arguments("테스트", 2, "테스트2"),
            Arguments.arguments("테스트", 3, "테스트3")
    );
}

6. 테스트 실행 조건 지정

Assumptions

assertj 의 Assumptions를 이용해서 테스트 조건을 지정할 수 있다. 아래와 같이 테스트코드에 입력하게 되면 참/거짓 결과에 따라서 하위의 테스트코드를 실행할지 결정된다.
Ex) Assumptions.assumeThat("실제값").isEqualTo("기대값")

@Enabled~ 어노테이션

@EnabledOnJre, @EnabledOnOs, @EnabledIf, @EnabledIfSystemProperty 등 @Enabled로 시작하는 어노테이션들이 있다. 각 필요에 따라 @Test 메소드위에 조건과 함께 설정해서 사용할 수 있다.

0개의 댓글