#개발 #java #테스트코드
정의: Java 생태계에서 제공하는 단위 테스트 프레임워크
(추가적으로 보고 싶은: - [Using Gradle in the Eclipse IDE](https://www.vogella.com/tutorials/EclipseGradle/article.html))
Junit
Junit 테스트는, 테스트 목적으로 만들어진 클래스 내에서 @Test 어노테이션이 붙은 메소드이다.
기대값과 실제 값을 비교하는 assert 구문을 이용하여 테스트를 할 수 있다.
특히 실패했을 경우 @DisplayName 어노테이션을 통해, 출력하는 메시지를 정하여 보다 수월하게 확인할 수 있다.
예시 코드
package com.vogella.junit5;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
class CalculatorTest {
Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
@DisplayName("Simple multiplication should work")
void testMultiply() {
assertEquals(20, calculator.multiply(4, 5),
"Regular multiplication should work");
}
@RepeatedTest(5)
@DisplayName("Ensure correct handling of zero")
void testMultiplyWithZero() {
assertEquals(0, calculator.multiply(0, 5), "Multiple with zero should be zero");
assertEquals(0, calculator.multiply(5, 0), "Multiple with zero should be zero");
}
}
static import : 클래스에서 public static으로 선언된 필드 및 메소드인 자바 기능.
다음과 같은 차이가 있다.
// without static imports you have to write the following statement
import org.junit.jupiter.api.Assertions;
// more code
Assert.assertEquals("10 x 5 must be 50", 50, tester.multiply(10, 5));
// alternatively define assertEquals as static import
import static org.junit.jupiter.api.Assertions.assertEquals;
// more code
// use assertEquals directly because of the static import
assertEquals(calculator.multiply(4,5), 20, "Regular multiplication should work");
간단한 assert 문
`org.junit.jupiter.api.Assertions.*` package. 에 있는 static method
오버헤드 방지를 위해서 람다 함수 형식으로 메시지를 작성하기도 한다.
assertTrue('a' < 'b', () -> "Assertion messages can be lazily evaluated -- " + "to avoid constructing complex messages unnecessarily.");
## 예외를 위한 테스트
org.junit.jupiter.api.Assertions.expectThrows()
import static org.junit.jupiter.api.Assertions.assertThrows;
@Test void exceptionTesting() {
// set up user
Throwable exception = assertThrows(IllegalArgumentException.class,
() -> user.setAge("23"));
assertEquals("Age must be an Integer.", exception.getMessage());
}
여러개의 assert 문을 사용하려고 할 때
@Test
void groupedAssertions() {
Address address = new Address();
assertAll("address name",
() -> assertEquals("John", address.getFirstName()),
() -> assertEquals("User", address.getLastName())
);
}
시간 제한 두기
assertTimeout()
import static org.junit.jupiter.api.Assertions.assertTimeout;
import static java.time.Duration.ofSeconds;
import static java.time.Duration.ofMinutes;
@Test
void timeoutNotExceeded() {
assertTimeout(ofMinutes(1), () -> service.doBackup());
}
// if you have to check a return value
@Test
void timeoutNotExceededWithResult() {
String actualResult = assertTimeout(ofSeconds(1), () -> {
return restService.request(request);
});
assertEquals(200, request.getStatus());
}
advance: dynamic test
컴파일 시점에만 돌아가는 테스트 코드와 달리,
다이나믹 테스트는 런타임 동안에 테스트가 생성되고 수행된다.
래서 프로그램이 수행되는 도중에도 동작을 변경할 수 있는 특징이 있다.
이 다이나믹 테스트는 `@Test` 어노테이션을 사용하지 않고, `@TestFactory` 어노테이션을 통해 팩토리 메서드로 생성된다.
장점:
- 정적 테스트는 지정해놓은 데이터만으로 테스트해야한다.
- 반면 다이나믹 테스트를 사용하면 데이터셋을 런타임 시점에 동적으로 가져와서 테스트를 수행할 수 있다. (getNumberFromDatatbase.. )
- 하나의 메소드 안에서 사용자 시나리오를 작성하는 경우, 가독성이 약해지고 BDD (행위 주도 개발)을 하는 의미가 약해진다.
- 다이나믹 테스트 같은 경우, 첫번째 인자로 테스트 제목을 붙일 수 있어서 가독성을 높일 수 있다고 한다.
방법
- @TestFactory 어노테이션 사용: 테스트 케이스를 생성하는 팩토리
private, static은 안된다.
- 컬렉션 반환
@TestFactory 메소드는 Stream, Collection, Iterable or Iterator를 return해야한다. (그렇지 않으면 JUnitException 발생)
- 첫번째 이름으로 테스트 이름 작성
기본 형식
@TestFactory
Stream<DynamicTest> exampleDynamicTest() {
return Stream.of(
dynamicTest("First Dynamic Test", () -> {
//test code
}),
dynamicTest("Second Dynamic Test", () -> {
//test code
}));
}
다이나믹 테스트는 생명주기 콜백함수를 지원하지 않기 때문에, @BeforeEach, @AfterEach 와 같은 테스트 생명 주기와 관련된 요소들을 사용할 수 없다.
'개발 > java' 카테고리의 다른 글
[Spring 기본] 4. 싱글톤 컨테이너 (0) | 2024.01.06 |
---|---|
[Spring 기본] 3. Spring 프레임워크 사용하기 (1) | 2023.12.21 |
Input 찬찬히 뜯어보기. (BufferedReader와 InputStreamReader?) (0) | 2023.12.11 |
[Spring 기본] 2. 실제 코드에서의 스프링 프레임워크 핵심 원리 (0) | 2023.12.08 |
[Spring 기본] 1. 객체 지향 설계와 스프링 (4) | 2023.12.08 |