인텔리제이를 사용하는 자바 개발자가 90% 이상 사용한다는 JUnit을 간단히 알아보러 한다.
자세한 내용은 공식 가이드를 참고하기 바란다.
JUnit 5
JUnit이란?
JUnit은 자바 프로그래밍 언어용 유닛 테스트 프레임워크이다. JUnit은 컴파일 타임에 JAR로서 링크된다. [위키백과]
JUnit5 구성요소
Junit5는 3가지로 구성되어 있다.
- JUnit Platform : JVM에서 테스트 프레임워크를 실행하는 기반, 테스트 엔진 API 제공
- JUnit Jupiter : 테스트를 작성하기 위한 프로그래밍 & 익스텐션 모델을 제공
- JUnit Vintage : 이전 버전을 위한 테스트 엔진 제공 (JUnit3 & JUnit4 호환)
왜 JUnit5 인가?
JUnit 시리즈 중에서 2017년에 공개된 JUnit5를 사용하는 이유를 한 문장으로 요약하자면
스프링 부트 2.2.x 버전부터는 기본적으로 JUnit5 제공하기 때문이다.
(JUnit5는 Java8 이상을 지원하고, JUnit4는 Java5 이상 지원)
JUnit5 추가하기
스프링 부트 2.2.x 이상이라면 기본적으로 제공되고 있다.
dependencies {
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
직접 추가해야한다면 다음과 같이 추가한다.
dependencies {
testImplementation(platform('org.junit:junit-bom:5.8.1'))
testImplementation('org.junit.jupiter:junit-jupiter')
}
test {
useJUnitPlatform()
}
만약에 Maven 이라면 다음과 같이 추가한다.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
JUnit5 Annotations
JUnit에서 제공하는 어노테이션은 클래스나 메소드, 파라미터에 적용이 가능하다.
다양하고 많은 어노테이션이 있으며, 우선 JUnit 핵심 어노테이션을 간단히 알아보자.
Method Annotataions
[테스트 지정]
메서드를 5가지 어노테이션으로 테스트로 지정할 수 있다.
@Test | 테스트를 뜻한다. |
@ParameterizedTest | 매개변수화 된 테스트를 뜻한다. |
@RepeatedTest | 반복적인 테스트를 뜻한다. |
@TestFactory | 동적 테스트를 뜻한다. |
@TestTemplate | 테스트 케이스에 대한 템플릿을 뜻한다. |
public class JUnitStartTest {
private final Calculator calculator = new Calculator();
@Test
void addition_01() {
assertEquals(2, calculator.add(1, 1));
}
@ParameterizedTest
@CsvSource(value = {"1,2,3"}, delimiter = ',')
void addition_02(int a, int b, int result) {
assertEquals(result, calculator.add(a, b));
}
@RepeatedTest(10)
void loop() {
}
...
}
[라이프 사이클]
테스트가 실행 전 & 후에 실행할 메서드를 지정할 수 있다.
@BeforeAll | 현재 클래스의 모든 테스트가 실행되기 전에 한번 실행된다. |
@BeforeEach | 각각 테스트가 실행 전에 실행한다. |
@AfterEach | 각각 테스트가 실행 후에 실행한다. |
@AfterAll | 현재 클래스의 모든 테스트가 실행된 후에 한번 실행된다. |
[시간 제한]
테스트 & 라이프사이클 어노테이션에 같이 사용된다.
@Timeout | 지정된 제한 시간을 초과하면 실패처리한다. |
[실행 순서]
테스트 실행 순서를 지정한다.
@Order | 테스트 메서드의 실행 순서를 지정한다. |
Class Annotataions
[인스턴스 전략]
인스턴스 생성 전략을 지정한다.
(JUnit은 기본적으로 테스트간의 의존성을 없애기 위해 테스트 메서드마다 독립적인 객체로 진행한다. )
@TestInstance | 현재 클래스의 모든 테스트가 실행되기 전에 한번 실행된다. |
[실행 순서]
@TestMethodOrder | 테스트 클래스의 실행 순서를 지정한다. |
[이름 표기]
@DisplayNameGeneration | 테스트 이름을 표기하는 방법을 설정한다. |
[non-static]
@Nested | 해당 클래스가 non-static 내부 클래스임을 나타낸다. @BeforeAll, @AfterAll을 사용할 수 없다. |
[확장]
@ExtendWith | 확장자를 선언적인 등록에 사용된다. |
@RegisterExtension | 프로그래밍으로 확장자를 등록하는데 사용한다. |
Class & Method Annotataions
[필터]
@Tag | 테스트 그룹을 만들고 원하는 그룹만 테스트할 수 있다. |
[이름 표시]
@DisplayName | 클래스명 & 메서드명 대신 노출한 이름을 지정한다. |
[비활성화]
@Disabled | 지정된 클래스, 메서드를 실행하지 않는다. |
Parameter Annotataions
[임시 디렉토리]
테스트 & 라이프사이클 어노테이션에 같이 사용된다.
@TempDir | 필드 및 파라미터 주입을 통해 임시 디텍토리로 사용된다. |
매개변수 테스트를 도와주는 Annotataions
@ParameterizedTest를 사용하다보면 다양한 인자값이 필요한데, 이를 지원하는 어노테이션 내역이다.
@ValueSource | 지정된 타입 & 배열 값을 넘겨준다. |
@NullSource | Null 값을 넘겨준다 |
@EmptySource | 비어있는 값을 넘겨준다 |
@NullAndEmptySource | Null과 비어있는 값을 넘겨준다. |
@EnumSource | 지정된 Enum을 넘겨준다. |
@MethodSource | 지정된 메서드의 반환 값을 넘겨준다. |
@CvsSource | 문자열로 이뤄진 배열 값을 넘긴다. 각 문자열은 특정 구분자로 분리되어 여러 타입으로 넘어온다. |
@CvsFileSource | 지정된 경로의 csv 파일을 읽어 값을 넘긴다. |
@ArgumentSource | 커스텀 데이터 값을 주입한다 |
Assertions
JUnit의 jupiter는 정적 단언 메서드를 제공한다.
assertEquals(A, B) | A와 B가 같은 값인지 확인 |
assertEquals(A, B, C) | A와 B가 같은 값인지 확인한다. C로 오차범위 지정이 가능하다. |
assertNotEquals(A, B) | A와 B가 서로 다른 값인지 확인 |
assertSame(A, B) | A와 B가 같은 객체인지 확인한다. |
assertTrue(A) | A가 True인지 확인 |
assertFalse(A) | A가 False인지 확인 |
assertNull(A) | A가 Null인지 확인 |
assertNotNull(A) | A가 존재하는지 확인 |
assertAll(executables...) | 모든 확인 구문 |
assertTimeout(duration, executable) | 지정된 시간안에 실행이 완료되는지 확인 |
그 외에도 많은 메서드를 제공한다.
작성 방법은 아래와 같이 간단하다.
import static org.junit.jupiter.api.Assertions.*;
public class JUnitStartTest {
@Test
void test_assertEquals_01() {
String a = "이름";
String b = "이름";
assertEquals(a, b);
}
@Test
void test_assertNotEquals_01() {
String a = "loop";
String b = "공부";
assertNotEquals(a, b);
}
@Test
void test_assertEquals_02() {
int a = 1;
int b = 2;
assertEquals(a, b, 1);
}
@Test
void test_assertSame() {
String a = "study";
String b = a;
assertSame(a, b);
}
@Test
void test_assertAll() {
assertAll(
() -> assertEquals("study", "study"),
() -> assertNotEquals("study", "loop"),
() -> assertNull(null),
() -> assertTrue(true)
);
}
}
JUnit에 내용은 많지만, 간단히 기초적인 내용만 언급하고 넘어간다.
참고자료
https://junit.org/junit5/docs/current/user-guide - 공식가이드
더 자바, 애플리케이션을 테스트하는 다양한 방법 - 인프런, 백기선
https://velog.io/@jaehoonlee/JUnit-5-공식-가이드-문서-정리 - 소프트웨어 개발자 이재훈
'개발 & 방법론 > TDD' 카테고리의 다른 글
Mockito 알아보기 (부제 : BDD) (1) | 2021.12.06 |
---|---|
AssertJ 알아보기 (부제 : Jupiter, Hamcrest 맛보기 ) (0) | 2021.11.21 |
테스트 코드를 작성하는 이유 (0) | 2021.03.03 |
테스트코드 첫걸음 (0) | 2021.02.15 |