일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 시뮬레이션
- JUnit 5
- 유니온 파인드
- 백준
- 수학
- java
- Network
- 완전탐색
- 스택
- 그리디
- CS
- Kotlin
- 에라토스테네스의 체
- mst
- 문자열
- dfs
- 백트래킹
- 프로그래머스
- BFS
- 위상정렬
- 동적계획법
- 세그먼트 트리
- 이분탐색
- swea
- 알고리즘
- 후니의 쉽게 쓴 시스코 네트워킹
- Effective Java
- 투 포인터
- 플로이드-와샬
- 구현
반갑습니다!
[JUnit 5] JUnit 5 - 2 본문
테스트 이름 표기하기
테스트를 실행시키면 메소드 이름으로 테스트가 진행되는 것을 볼 수 있다. 때문에 메소드 이름이 길어질수록 가독성이 떨어진다는 단점이 있다. 이를 보완하기 위해서 JUnit 5에서는 테스트의 이름을 표시할 수 있는 기능을 제공한다.
Java에서는 메소드 이름을 Camel 표기법으로 작성한다. 하지만 이는 가독성 측면에서 봤을 때 Snake 표기법보다 떨어진다. 이 때문에 테스트 코드를 작성할 때는 Snake 표기법으로 작성한다.
@DisplayNameGeneration
이 Annotaion은 DisplayNameGenerator
클래스에 구현된 몇 가지 옵션을 통해 테스트의 가독성을 올려준다.
- Standard : 기본 JUnit 5의 이름 생성과 동일
- ReplaceUnderscores : _를 공백으로 변경한다.
이번 포스팅에서는 DisplayNameGenerator.ReplaceUnderscores
로 진행해보겠다.
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class CalculatorTest {
@Test
void create_calculator_test() {
System.out.println("create calculator test");
Calculator calculator = new Calculator();
assertNotNull(calculator);
}
@Test
void add_test() {
System.out.println("add function test");
Calculator calculator = new Calculator();
assertEquals(4, calculator.add(2, 2));
}
}
실행 결과
왼쪽의 테스트 결과 창에 메소드 이름에 포함된 _ 가 모두 공백으로 변경된 것을 확인할 수 있다.
@DisplayName
@DisplayNameGenerator
에 대해 학습했지만, 이것만으로 테스트 코드의 가독성이 올라갔다고 보기는 어렵다. 그래서 JUnit 5에서는 더 강력한 기능을 제공한다. @DisplayName
Annotaion 선언을 통해 원하는 이름으로 테스트를 확인할 수 있다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@DisplayName("계산기 테스트")
class CalculatorTest {
@DisplayName("계산기 객체 생성 테스트")
@Test
void create_calculator_test() {
System.out.println("create calculator test");
Calculator calculator = new Calculator();
assertNotNull(calculator);
}
@DisplayName("덧샘 테스트")
@Test
void add_test() {
System.out.println("add function test");
Calculator calculator = new Calculator();
assertEquals(4, calculator.add(2, 2));
}
}
실행 결과
테스트 이름이 @DisplayName
에서 지정한대로 출력됨을 확인할 수 있다.
참고로 @DisplayNameGeneration
보다 우선 순위가 높다.
Assertion
@Test
Annotaion에 대해 학습하면서 assertNotNull()
메소드를 사용했었다. 이번엔 좀 더 다양한 메소드들을 알아보자.
앞서 언급했듯 Assertions
클래스에는 다양한 메소드가 구현되어있다.
메소드 이름이 직관적이라 사용하는데 큰 어려움은 없을 것이다.
org.junit.jupiter.api.Assertions.*
Method Name | Description |
assertEquals(expected, actual) | 실제 값이 기대한 값과 같은지 확인 |
assertNotNull(actual) | 값이 null이 아닌지 확인 |
assertAll(executables...) | 다음 조건이 true인지 확인 |
assertThrows(exptectedType, executable) | 예외 발생 확인 |
assertTimeout(duration, executable) | 특정 시간 안에 실행이 완료되는지 확인 |
해당 메소드들을 사용해 테스트를 진행하면 된다.
assertAll()
하나의 테스트 코드에서 여러 조건을 테스트할 수 있다. 하지만 이럴 경우 먼저 실행되는 테스트가 실패하게 되면 그 뒤에 테스트는 실행되지 않는다. 이러한 문제는 assertAll()
를 통해 해결할 수 있다.
우선 테스트가 실패하도록 해보자.
import org.junit.jupiter.api.Test;
class CalculatorTest {
@Test
void create_calculator_test() {
Calculator calculator = new Calculator();
assertNull(calculator);
System.out.println("create calculator test");
}
}
실행 결과
assertNull()
에서 테스트가 종료되어 그 다음 줄이 실행되지 않는다.
이번에는 assertAll()
를 사용해 테스트 코드를 작성해보자. assertAll()
메소드는 Executable
객체를 인자로 받아서 실행한다. 따라서 Executable
객체를 생성해서 인자로 전달해주어도 되고, 익명 객체를 생성해줘도 된다. 하지만 아래의 코드에서는 람다식으로 구현했음을 유의하자.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertNull;
class CalculatorTest {
@Test
void create_calculator_test() {
Calculator calculator = new Calculator();
assertAll(
() -> assertNull(calculator),
() -> System.out.println("create calculator test")
);
}
}
실행 결과
테스트가 중간에 실패했지만, 그 이후로도 코드가 진행되었다.
테스트 실패 메시지
테스트가 실패했을 때, 지정한 메시지를 출력해준다면 이에 대한 처리가 훨씬 더 수월할 것이다. 이를 위해 assert 메소드들에 실패 메시지를 추가할 수 있다.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class CalculatorTest {
@Test
void create_calculator_test() {
Calculator calculator = null;
assertNotNull(calculator, "Calculator 객체는 null이면 안된다.");
}
}
실행 결과
미리 작성해 둔 실패 메시지가 같이 출력된다.
테스트 실패
실패 메시지를 작성할 때 "Test " + number + " is fail"
처럼 String
연산을 통해 메시지가 작성될 수 있다. 이런 경우 String
연산을 수행하는데 비용이 든다. 만약 테스트가 항상 성공하는데, 실패 메시지를 위해서 String
연산을 항상 수행한다면 이는 낭비가 될 것이다. 따라서 assert 메소드들은 이를 방지할 수 있도록 Supplier<String>
객체를 통해 실패 메시지를 전달받을 수 있도록 구현되어 있다.
import org.junit.jupiter.api.Test;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class CalculatorTest {
@Test
void create_calculator_test() {
Calculator calculator = null;
// 익명 객체 사용
assertNotNull(calculator, new Supplier<String>() {
@Override
public String get() {
return "Calculator 객체는 null이면 안된다.";
}
});
// 람다식 사용
assertNotNull(calculator, () -> "Calculator 객체는 null이면 안된다.");
}
}
위의 코드처럼 익명 객체 또는 람다식을 통해 실패 메시지를 작성하면, 테스트가 실패한 경우에만 String
연산을 수행해 연산 수행 비용을 절약할 수 있다.
'개발' 카테고리의 다른 글
[Effective Java] 아이템 2: 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2021.07.22 |
---|---|
[Effective Java] 아이템 1: 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2021.07.22 |
[JUnit 5] JUnit 5 - 1 (0) | 2020.12.27 |
[Java] Java Reference (0) | 2020.10.15 |
[Java] Garbage Collection (0) | 2020.10.15 |