티스토리 뷰
우테코 프리코스를 하다보니 테스트 코드를 작성할 일이 자주 생겼다.
오랜만에 작성해보니까 헷갈려서.. 자주 쓰이는 어노테이션과 함수들을 정리해보려고 한다.
Junit
자바를 위한 단위 테스트 라이브러리.
Junit 어노테이션
- @Test
- 함수 위에 선언해 테스트 함수임을 지정
- @Test(timeout=밀리초)
- 테스트 함수의 수행 시간을 제한
- 테스트할 함수가 수행되는 시간이 어노테이션 매개변수로 지정한 시간을 넘긴다면 fail
- @Test(expected=예외)
- 테스트할 함수의 예외를 지정
- 매개변수로 지정한 예외가 발생해야 테스트 pass
- @Ignore
- 해당 어노테이션이 선언된 테스트 함수는 무시하도록 지정
- @BeforeEach
- 해당 어노테이션이 선언된 함수는 모든 @Test 함수가 실행되기 전에 실행된다.
- 테스트 전에 리셋되어야 할 항목이 들어간다.
- @AfterEach
- 해당 어노테이션이 선언된 함수는 모든 @Test 함수가 실행된 후 실행된다.
- @BeforeAll
- 모든 @Test 함수가 실행되기 한번만 실행된다.
- @AfterAll
- 모든 @Test 함수가 실행된 후 한번만 실행된다.
- @Nested
- 정적이 아닌 중첩된 테스트 클래스임을 지정
- @DisplayName
- 테스트 클래스나 함수에 설명을 추가
테스트 클래스에 @Test 함수가 두개 있다고 가정했을 때, 어노테이션 실행 순서는 아래와 같다.
BeforeAll -> BeforeEach -> Test -> AfterEach -> BeforEach -> Test -> AfterEach -> AfterAll
Junit 함수
assertEquals(expected, actual)
하나의 값을 단순 비교할 때는 assertEquals()를 사용한다.
3번째 인자로 테스트가 실패했을 경우 띄울 메시지를 넣을 수 있다.
assertAll("message",
() -> assertEquals(result1, actual1),
() -> assertEquals(result2, actual2)
)
여러개를 한번에 테스트하고 싶은 경우 assertAll()을 사용한다.
Assertion 함수들은 Junit보다 AssertJ의 함수들을 주로 사용하는 것 같다.
더 많은 함수들은 아래 링크 참고!
https://junit.org/junit5/docs/5.10.0/api/org.junit.jupiter.api/org/junit/jupiter/api/Assertions.html
Assertions (JUnit 5.10.0 API)
Assert that all supplied executables do not throw exceptions. If any supplied Executable throws an exception (i.e., a Throwable or any subclass thereof), all remaining executables will still be executed, and all exceptions will be aggregated and reported i
junit.org
AssertJ
Junit 테스트 코드에 사용되어 가독성과 편의성을 높여주는 라이브러리.
val result = "Hello World".substring(0, 5)
assertThat(result)
.isNotEmpty()
.contains("Hello")
.doseNotContain("World")
.startWith("H")
.endWith("o")
.isEqualTo("Hello")
이런식으로 함수를 연쇄적으로 호출하여 직관적인 코드를 작성할 수 있는다는 것이 AssertJ의 특징이다.
assertThat(result).isEqualTo(expect)
주로 위와 같은 코드로 사용한다.
result가 expect와 같으면 pass.
assertThat(result)
.`as`("Assertion 설명")
.isEqualTo(expect)
as()를 통해 코드에 대한 설명을 추가할 수 있다.
이 설명이 테스트 결과에 출력된다.
또한 결과를 비교하는 assertion 함수들을 호출하기 전에 사용해야 한다.
(코틀린은 as가 예약어로 사용되기 때문에 as를 ``로 감싸줘야 한다..)
예외 처리
assertThatCode { ... }
.doesNotThrowAnyException()
단순히 예외가 발생하지 않았음을 테스트하고 싶은 경우 doseNotThrowAnyException()을 호출한다.
assertThatCode 안에 테스트하고 싶은 코드가 들어간다.
assertThatThrownBy { ... }
.isInstanceOf(IllegalArgumentException::class.java)
.hasMessage(EXCEPTION_MESSAGE)
예외 발생하는 코드를 테스트하고 싶은 경우 assertThatThrownBy를 사용한다.
{} 안에 테스트하고 싶은 코드(예외를 던져야 함)가 들어간다.
isInstanceOf()를 통해 실제 발생한 예외와 인자로 들어간 예외 타입이 같은지 확인한다.
hasMessage()를 통해 실제 발생한 예외의 메시지가 인자의 메시지가 같은지 확인한다.
기타
- isPositive(), isNegative() : 값이 양수인지, 음수인지 확인
- isBetween(start, end) : 값이 start와 end 사이의 값인지 확인 (start <= result <= end)
- isGreaterThan(a) : 값이 a보다 큰지 확인
- isLessThan(a) : 값이 a보다 작은지 확인
더 많은 함수들은 아래 링크 참고!
https://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html
AssertJ / Fluent assertions for java
AssertJ has many great features that not everybody is aware of, here are some of them. Basic tips : Iterable and arrays assertions : Advanced tips : We want to start typing asser and let code completion suggest assertThat from AssertJ (and not the one from
joel-costigliola.github.io
+ Given-When-Then Pattern
// given (테스트할 함수의 인자로 넣을 데이터)
val case1 = ...
val case2 = ...
val case3 = ...
// when (case1, case2, case3의 데이터를 사용해서 테스트할 함수 호출)
val result1 = ...
val result2 = ...
val result3 = ...
// then (함수 호출한 결과를 확인)
assertThat(result1).isEqualTo(...)
assertThat(result2).isEqualTo(...)
assertThat(result3).isEqualTo(...)
테스트 코드 작성 시 준비-실행-검증 의 세 부분으로 나누는 것이다.
꼭 따라야 할 패턴은 아니지만, 테스트 코드를 어떻게 작성할지 감이 안 잡힐 때 도움이 많이 되었다.
테스트 코드를 작성해본 경험이 많이 없어서 지저분하게 작성하게 되는 것같다..
테스트 함수명도 문장으로 작성하거나 재활용할 수 있는 부분들을 분리하는 것들을 연습해봐야겠다.
'kotlin' 카테고리의 다른 글
[코틀린/kotlin] 영역 함수 (scope function) also, let, run, with, apply (1) | 2023.11.01 |
---|---|
[코틀린/kotlin] 콘솔창에 출력된 값 테스트하기 (AssertJ, Junit) (0) | 2023.10.31 |
코틀린으로 코딩테스트 준비하기 (0) | 2023.10.18 |
[kotlin/코틀린] 코루틴 동시성 통신 (채널, 프로듀서, 티커, 액터, 플로우) (0) | 2023.07.20 |
[kotlin/코틀린] 코루틴 흐름 제어 (Job, 타임아웃, 디스패처, 예외 처리) (0) | 2023.07.20 |