Java

[Java] JUnit이란? Assert(단정 메서드), Lifecycle(라이프사이클 메서드)

cloud-grace 2024. 5. 24. 17:54

JUnit이란?

JUnit은 Java 로 단위 테스트를 할 수 있는 라이브러리이다. 개발자들은 개별 코드 단위(메서드, 클래스 등)를 테스트 하고 그 동작이 기대한 대로 수행되는지 확인할 수 있다.

  • 단정 메서드(assert~~)로 테스트 케이스의 수행 결과를 판별할 수 있다.
  • 테스트 메서드를 정의하고 관리하기 위해 다양한 어노테이션을 제공한다.
  • 테스트 결과로 성공 or 실패를 확인하고 오류를 확인하고 저장할 수 있다.


Unit Test 단위 테스트

단위 테스트는 소프트웨어 개발에서 개별 단위(주로 메서드, 클래스)를 테스트하는 것이다. 각 단위가 올바르게 작동하는지 확인하고 의도대로 정확히 동작하는지 테스트한다.

JUnit 어노테이션

@Test

  • 해당 메서드가 테스트 메서드임을 나타낸다.

@Test(expected=예외)

  • 해당 테스트 메소드가 예외 발생이 되었는지 성공 or 실패를 확인할 수 있다.
@Test(expected = ArithmeticException.class)
public void testDivideByZero() {
    int result = calculator.divide(1, 0);
}
  • 다른 방법으로 assertThrows 메서드를 사용해서 특정 예외가 발생하는지 검증 가능하다.
@Test
void testDivideByZero() {
    assertThrows(ArithmeticException.class, () -> calculator.divide(1, 0));
}

@Test(timeout=밀리초)

  • 테스트 메서드가 지정된 시간 내에 완료되지 않으면 실패로 간주한다.
@Test(timeout = 1000)
public void testDivideByZero() {
    int result = calculator.divide(1, 0);
}
  • 다른 방법으로 @Timeout을 사용해서 테스트 메서드 실행 시간을 제한할 수 도 있다.
import org.junit.jupiter.api.Timeout;
import java.util.concurrent.TimeUnit;

@Test
@Timeout(value = 1, unit = TimeUnit.SECONDS)
void testDivideByZero() {
    assertThrows(ArithmeticException.class, () -> calculator.divide(1, 0));
}

@Disabled (@Ignore in JUnit 4)

  • 특정 테스트 메서드를 비활성화한다.

JUnit Lifecycle 라이프사이클 메서드 (JUnit 5)

실행 순서

( ) 괄호 부분이 반복된다.
@BeforeAll → (@BeforeEach → @Test → @AfterEach → @BeforeEach → @Test → @AfterEach) → @AfterAll

@BeforeEach (@Before in JUnit4)

  • 각각의 모든 테스트 메서드가 실행되기 전에 실행될 메서드를 지정한다.
  • @Test 메서드에서 공통으로 사용될 코드나 리셋되어야 할 부분을 넣으면 좋다.

@AfterEach (@After in JUnit4)

  • 각각의 모든 테스트 메서드가 실행되고 난 후에 실행될 메서드를 지정한다.

@BeforeAll (@BeforeClass in JUnit4)

  • 모든 테스트 클래스 실행되기 전 딱 1번만 실행되는 메서드이다.

@AfterAll (@AfterClass in JUnit4)

  • 모든 테스트 클래스 실행된 후에 딱 1번만 실행되는 메서드이다.

JUnit assert 메서드

  • assertEquals(expected, actual): 예상 값과 실제 값이 같은지 확인한다.
  • assertEquals(expected, actual, delta): 부동 소수점 비교를 위한 허용 오차를 포함하는 메서드이다. delta는 오차 범위이다.
  • assertTrue(condition): 조건이 참인지 확인한다.
  • assertFalse(condition): 조건이 거짓인지 확인한다.
  • assertNull(object): 객체가 NULL인지 확인한다.
  • assertNotNull(object): 객체가 NULL이 아닌지 확인한다.
  • assertThrows(expectedType, executable): 지정된 타입의 예외가 발생하는지 확인한다.
  • assertArrayEquals(expectedArray, actualArray): 두 배열의 모든 요소가 같은지 비교한다.
  • assertSame(expected, actual): 두 객체가 동일한 객체(참조가 같은지)인지 비교한다.
  • assertTimeout(duration, executable): 지정된 시간 내에 실행이 완료되는지 확인한다.

예제 코드

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;

public class AssertionExamples {

    @Test
    void testAssertEquals() {
        int expected = 5;
        int actual = 2 + 3;
        assertEquals(expected, actual); // 5 == 5, 통과
    }

    @Test
    void testAssertArrayEquals() {
        int[] expected = {1, 2, 3};
        int[] actual = {1, 2, 3};
        assertArrayEquals(expected, actual); // 통과
    }

    @Test
    void testAssertSame() {
        String a = "hello";
        String b = "hello";
        String c = new String("hello");
        
        assertSame(a, b); // 통과
        assertNotSame(a, c); // 통과
    }

    @Test
    void testAssertTimeout() {
        assertTimeout(ofSeconds(1), () -> {
            // 1초 이내 완료되는 작업
            Thread.sleep(500);
        }); // 1초 이내 완료되므로 통과
    }
}

AssertJ란?

  • Java JUnit의 기본 assertion 메서드를 보완하여 더 직관적이고 가독성 좋은 테스트 코드를 작성하게 해준다.
  • 체이닝 기법을 통해 다양한 검증을 한 줄로 작성할 수 있다.
  • 테스트에 필요한 메서드가 매우 많다.
  • AssertJ의 모든 테스트 코드는 assertThat(actual)로 검증을 시작한다.
  • 메서드 체이닝 기법을 통해 assertThat(actual).메서드().메서드().메서드()... 이런 형식으로 작성한다.

AssertJ 메서드

  • assertThat(actual): 검증을 시작한다.
  • isEqualTo(expected): 예상 값과 실제 값이 같은지 확인한다.
  • isNotNull(): 객체가 null이 아닌지 확인한다.
  • isTrue(): 조건이 참인지 확인한다.
  • isFalse(): 조건이 거짓인지 확인한다.
  • contains(expected): 컬렉션이나 배열에 특정 값이 포함되어 있는지 확인한다.
  • hasSize(size): 컬렉션이나 배열의 크기를 확인한다.

AssertJ 예제 코드

import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;

public class AssertionExamples {

    @Test
    void testAssertJ() {
        String text = "Hello, World!";
        int[] numbers = {1, 2, 3, 4, 5};
        Object obj = new Object();
        boolean condition = true;

        assertThat(text).startsWith("Hello").endsWith("!");
        assertThat(numbers).hasSize(5).contains(3).doesNotContain(6);
        assertThat(obj).isNotNull().isInstanceOf(Object.class);
        assertThat(condition).isTrue();
    }
}