*Assertion
Assetion은 테스트할 때 가장많이 사용되는 Class이다.
테스트할때 개발자가 의도한 값이 올바르게 출력되는지 확인시켜주는 다양한 Method가 존재한다.
먼저 Assertion에서 많이 사용되는 Method에 대해 araboza!
assertNotNull | 값이 null이 아닌지 확인 |
assertEquals | 기대값과 실제값이 일치하는지 확인 |
assertTrue | 조건이 참(True)인지 확인 |
assertAll | 모든 확인 구문 확인 |
assertThrows | 예외 발생 확인 |
assertTimeout | 특정 시간 안에 실행이 완료되는지 확인 |
위의 Assert 관련 메소드는 마지막에 실패했을 때 출력할 메시지 인자값을 추가해 줄수도 있다.
ex) assertNotNull(actualVal, 실패시 메시지); 이런식으로!
그렇다면 Method를 하나하나 사용해보자.
- assertEquals
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
Study study = new Study();
assertEquals(StudyStatus.DRAFT, study.getStatus(), "study를 처음 만들면 상태는 DRAFT여야 한다.");
}
}
여기서 메시지를 위처럼 그냥 String형태로 바로 써서 넘겨주게 되면, 해당 테스트코드가 성공시에서 String 코드에 대한 연산을 실행한다.
따라서 단일 텍스트가 아니라, + 로 String을 계속 붙여서 쓰는 경우에는 불필요한 연산을 테스트마다 실행하게 된다.
이를 방지하기위해 아래와 같이 람다로 표현하면 테스트 실패시에만 String 연산을 하게 된다.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
Study study = new Study();
assertEquals(StudyStatus.DRAFT, study.getStatus(), ()->"study를 처음 만들면 상태는 DRAFT여야 한다.");
}
}
- assertTrue
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
Study study = new Study(-10);
assertEquals(StudyStatus.DRAFT, study.getStatus(), ()->"study를 처음 만들면 "+ StudyStatus.DRAFT +"여야 한다.");
assertTrue(study.getLimit() > 0, "스터디 참석인원은 0명보다 많아야 합니다.");
}
}
해당 위의 코드라인에서 만약 테스트시 assetEquals가 실패했다면 assertTrue까지 도달하지 못한다.
이럴 경우 모두 묶어서 테스트를 진행해주는게 assertAll이다.
- assertAll
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
Study study = new Study(-10);
assertAll(
() -> assertNotNull(study),
() -> assertEquals(StudyStatus.DRAFT, study.getStatus(), ()->"study를 처음 만들면 "+ StudyStatus.DRAFT +"여야 한다."),
() -> assertTrue(study.getLimit() > 0, "스터디 참석인원은 0명보다 많아야 합니다.")
);
}
}
아래와 같이 assertAll은 Functional Interface인 Executable 인자로 받으므로 위와 같이 각각 람다로 표현해줘야 한다.
public static void assertAll(Executable... executables) throws MultipleFailuresError {
AssertAll.assertAll(executables);
}
- assertThrows
예외를 발생하기 위해 임시로 예외처리를 해주자.
public class Study {
private StudyStatus status;// = StudyStatus.DRAFT;
private int limit;
public Study(int limit) {
if(limit < 0) {
throw new IllegalArgumentException("limit은 0보다 커야합니다!");
}
this.limit = limit;
}
public StudyStatus getStatus() {
return this.status;
}
public int getLimit() {
return this.limit;
}
}
해당 Exception이 올바르게 처리가 된 모습니다.
또한 아래와 같이 Exception 메시지를 꺼내서 기대 값과 비교해 줄 수 있다.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> new Study(-1));
String message = exception.getMessage();
assertEquals("limit은 0보다 커야합니다!", message);
}
}
- assertTimeout
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
assertTimeout(Duration.ofSeconds(10), ()-> new Study(10));
}
}
위와 같이 해당 기대한 시간안에 코드라인이 종료되면 성공하게 된다.
반대로 테스트 실패코드도 작성해보자.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
assertTimeout(Duration.ofMillis(100), () -> {
new Study(10);
Thread.sleep(300);
});
}
}
만약 이렇게 기대한 시간보다 람다에서 진행되는 코드라인의 런타임이 더 오래 걸릴 경우, 테스트에서 런타임 코드라인을 다 기다리게 된다.
만약, 기대하는 시간보다 런타임 코드라인이 오래 걸리면 바로 테스트를 실패로 처리하고 종료하길 원한다면 아래와 같이 assertTimeoutPreemptively를 사용하면 된다.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기 ")
void create_new_study() {
assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
new Study(10);
Thread.sleep(300);
});
}
}
Assertion에 대해 이 정도로 정리하고 마무리하자.
끗!
'Framework > ✔️JUnit5' 카테고리의 다른 글
TDD를 위한 JUnit5 사용법 4 - 테스트 반복하기 (RepeatedTest, ParameterizedTest) (0) | 2022.09.06 |
---|---|
TDD를 위한 JUnit5 사용법 3 - 조건, 환경에 따른 테스트 실행 (0) | 2022.09.03 |
TDD를 위한 JUnit5 사용법 1 - JUnit5 개요 및 Naming Annotation (0) | 2022.08.14 |
댓글