Programming/JAVA

JUnit이란?

잇나우 2020. 12. 31. 00:14
반응형

JUnit

JUnit이란 java의 단위 테스트(Unit Test) 도구이다. 테스트 결과를 문서로 남기는 것이 아니라 Test Class 자체를 남겨 리팩토링을 하거나 소스코드가 변해도 해당 코드가 제대로 동작하는지 테스트 코드를 가지고 그대로 테스트 할 수도 있고, 미래에 이 기능을 맡게될 개발자에게 테스트 방법 및 클래스의 histroy를 넘겨줄 수도 있다. 하나의 jar파일로 되어있다.

단위 테스트

  • 소스코드의 특정 모듈이 의도된 대로 작동하는지 검증하는 절차
  • 모든 메서드에 대한 테스트 케이스를 작성하는 절차

JUnit4부터는 @어노테이션을 지원하여 간단하게 테스트할 수 있는 환경을 제공한다. (@Test, @Before ...) 테스트의 결과는 성공은 초록색, 실패는 빨간색으로 표시된다. 테스트 결과를 확인하는 것 뿐만 아니라 최적화된 코드를 유추하는 기능도 제공한다.

JUnit 5

JUnit 5는 크게 3가지 하위 프로젝트의 여러 모듈로 구성되어 있다.

JUnit 5 = JUnit plattform + JUnit Jupiter + JUnit Vintage
  • JUnit Platform
    • JVM에서 테스트 프레임워크를 시작하기 위한 기반 역할을 한다.
    • 테스트하기 위한 TestEngine API를 제공한다.
    • Command line을 사용할 수 있는 Console Launcher 제공한다.
    • JUnit 4 기반의 테스트를 제공
  • JUnit Jupiter
    • JUnit 5에서 테스트 및 확장을 위한 새로운 프로그래밍 모델과 확장 모델의 조합이다.
    • Platform에서 Jupiter 기반 테스트를 실행하기위한 TestEngine을 제공한다.
  • JUnit Vintage
    • Platform에서 JUnit 3와 JUnit 4 기반의 테스트를 할 수 있는 TestEngine을 제공한다.

Platform JUnit의 전반적인 테스트 API들을 제공하고 있고 이를 구현한 Jupiter와 Vintage가 존재한다고 볼 수 있다. JUnit 5는 Java 8버전 이상이 필요하다. 그러나 이전 버전의 JDK로 컴파일된 코드들은 계속 테스트 할 수 있다.

// 가장 기본적인 테스트의 예시
class  MyFirstJUnitJupiterTests  {  
    private final Calculator calculator = new Calculator();

    @Test
    void addition() {
        assertEquals(2, calculator.add(1, 1));
    }
 }

Annotations

Annotation Description
@Test 테스트 메서드임을 나타낸다.
Jupiter에서는 자체 어노테이션을 기반으로 사용하기 때문에 JUnit 4의 @Test 와는 달리 속성을 선언하지 않는다.
@ParameterizedTest 여러개의 파라미터에 대해서 테스트를 할 수 있다.
@RepeatedTest 반복횟수 만큼 테스트를 반복한다.
@TestFactory 동적 테스트 (dynamic tests)를 할 수 있는 어노테이션,
동적으로 생성되는 테스트를 생성할 수 있다. @TestFactory 메소드는 테스트 케이스가 아니라 테스트 케이스의 팩토리입니다.
@TestTemplate 등록된 제공자가 리턴한 호출 컨텍스트의 수에 따라 여러번 호출되도록 설계된 테스트 케이스의 템플릿임을 알리는 어노테이션
@TestMethodOrder 테스트 메소드의 실행 순서를 구성하는데 사용한다.
JUnit 4의 @FixMethodOrder와 유사하다)
@TestInstance 테스트 인스턴스의 lifecycle을 구성하는데 사용한다.
@DisplayName 테스트 클래스 또는 테스트 메서드에 커스텀 이름을 선언
@DisplayNameGeneration 테스트 클래스에 대한 Display name generator를 선언,
@DisplayName으로 제공된 값은 @DisplayGeneration으로 제공되는 것보다 우선된다.
@BeforeEach @Test, @RepeatedTest, @ParameterizedTest 또는 @TestFactory가 달린 각각의 메서드들 보다 먼저 실행되게하는 어노테이션,
JUnit 4의 @Before와 유사하다
@AfterEach @Test, @RepeatedTest, @ParameterizedTest 또는 @TestFactory가 달린 각각의 메서드들에 실행 이후에 실행되게하는 어노테이션,
JUnit 4의 @After와 유사하다
@BeforeAll @Test, @RepeatedTest, @ParameterizedTest 또는 @TestFactory가 달린 모든 메서드들 보다 먼저 실행되게하는 어노테이션,
JUnit 4의 @BeforeClass와 유사하다
@AfterAll @Test, @RepeatedTest, @ParameterizedTest 또는 @TestFactory가 달린 모든 메서드들에 실행 이후에 실행되게하는 어노테이션,
JUnit 4의 @AfterClass와 유사하다
@Nested static이 아닌 중첩 테스트 클래스임을 알리는 어노테이션
클래스 별 테스트 인스턴스 lifecycle을 사용하지 않는 한 @BeforeAll@AfterAll 메서드에서는 사용이 불가하다.
@Tag 테스트 검색 및 실행을 필터링할 수 있는 테스트 필터링을 위한 태그임을 알리는데 사용된다.
@Disabled 테스트 클래스 또는 테스트 메소드를 비활성화 하는데 사용한다.
JUnit 4의 @Ignore와 유사하다.
@Timout 주어진 시간을 초과할 경우 테스트 실패를 나타내기 위해 사용된다.
@ExtendWith 확장을 선언적으로 등록하는데 사용된다.
@RegisterExtension 필드를 통해 프로그래밍 방식으로 확장을 등록하는데 사용된다.
@TempDir 필드 주입, 매개변수 주입을 통해 임시 디렉토리를 제공하는데 사용된다.

Assertions

컴퓨터 프로그래밍에서 표명, 가정 설정문이라고 볼 수 있다. 프로그램 안에 추가하는 참과 거짓을 미리 가정하는 문이다. 이것을 이용하여 자신의 로직이 맞는지 테스트 해보는 것이다. Jupiter에서는 JUnit 4가 가지고 있는 많은 assertion 메서드와 함께 제공되며 Java 8 람다와 함께 사용하기에 적합한 추가적인 메서드를 제공한다. 모든 Assertion은 정적 메서드로 정의되어 있다.

private final Calculator calculator = new Calculator();
private final Person person = new Person("Jane", "Doe");

@Test
void standardAssertions() {
    assertEquals(2, calculator.add(1, 1));
    assertEquals(4, calculator.multiply(2, 2), "선택적 실패 메시지");
    assertTrue('a' < 'b', () -> "Assertion 메시지는 느리게 평가될 수 있다. 복잡한 메시지를 구성하는것을 방지");
}

@Test
void groupedAssertions() {
    assertAll("person",
        () -> assertEquals("jane", person.getFirstName()),
        () -> assertEquals("Doe", person.getLastName())
    );
}

@Test
void timeoutNotExceeded() {
    assertTimeout(ofMinutes(2), () -> {
        // 2분 미만의 로직만 통과
    }
}

많이 제공되는 Assertion 외에도 서드파티 라이브러리를 통해 Assertion도 가능하다.

Assumptions

테스터가 작성한 가정을 기반으로 테스트를 진행할지 안할지 선택된다. 설정한 가정이 참일 경우에는 테스트를 실행, 거짓일 경우에는 테스트를 실행하지 않는다. Asssumption은 단위 테스트보다는 통합 테스트에서 더 적절히 사용할 수 있다. Assertion과 마찬가지고 static 메서드로 정의되어 있다.

private final Calculator calculator = new Calculator();

@Test
void testOnlyOnCiServer() {
    assumeTrue("CI".equals(System.getenv("ENV")));
    // 나머지 테스트
}

@Test
void testOnlyOnDeveloperWorkstations() {
    assumeTrue("DEV".equals(System.getenv("ENV")),
        () -> "테스트 중단 : 개발자 워크 스테이션에 없음");
}

@Test
void testInAllEnvironments() {
    assumingThat("CI".equals(System.getenv("ENV")),
        () -> {
            // CI 서버에서만 assertion 수행
            assertEquals(2, calculator.divide(4, 2));
        });
    // 모든 환경에서 assertion 수행
    assertEquals(42, calculator.multiply(6, 7));
}

참고
https://github.com/jongnan/Java_Study_With_Whiteship/blob/master/week4/week4_0.md
https://junit.org/junit5/docs/current/user-guide/#overview
https://beomseok95.tistory.com/303#Assertions_

반응형

'Programming > JAVA' 카테고리의 다른 글

상속이란?  (0) 2021.01.07
클래스란?  (0) 2021.01.04
제어문이란?  (0) 2020.12.29
연산자란?  (0) 2020.12.22
데이터 타입, 변수, 배열 그리고 타입추론  (0) 2020.12.21