TDD(Test Driven Development) - Hamcrest (3)

아래 내용은 ‘테스트 주도 개발: TDD 실천법과 도구’(https://repo.yona.io/doortts/blog/issue/1)를 보고 주요 내용을 개인적으로 정리하여 작성했습니다.

Hamcrest ?


단순히 값 비교, 참/거짓 비교 등을 떠나 좀 더 유연하게 테스트를 할 수 있게 지원해주는 Matcher 라이브러리이다. Matcher 라이브러리는 ‘필터나 검색 등을 위해 값을 비교할 때 좀 더 편리하게 사용할 수 있게 도와주는 라이브러리.’ 라고 한다. 예전에는 JUnit 라이브러리와 같이 쓰면 좋은 정도의 외부 라이브러리였지만 편리함과 많은 사람들의 쓰임으로 인해 JUnit 라이브러리에 아예 포함되었다. 하지만 JUnit 5 에 와서는 Hamcrest 에서 사용되는 assertThat 문이 빠지게 되었다.

JUnit 5 공식문서에 보면 다음과 같이 나와있다.

For example, the combination of matchers and a fluent API can be used to make assertions more descriptive and readable. However, JUnit Jupiter’s org.junit.jupiter.api.Assertions class does not provide an assertThat() method like the one found in JUnit 4’s org.junit.Assert class which accepts a Hamcrest Matcher. Instead, developers are encouraged to use the built-in support for matchers provided by third-party assertion libraries.

자세한 이유는 안나와있어서 잘 모르겠다만 결과적으로 assertThat 과 같은 구문을 사용하고 싶으면 써드파티 라이브러리를 사용하라는 말이다. 얘기를 쭉 이어 나가자면 왜 Hamcrest 같은 Matcher 라이브러리가 좀 더 유연하고 문법적으로 친숙하냐고 궁금할 수 있다. 그럼 잠시 Hamcrest 예제와 JUnit 예제를 비교해보자

// JUnit 
assertEquals(true, true);
// Hamcrest (Matcher)
assertThat(true, is(true));

딸랑 두개뿐인 메소드지만 잘 보면 차이를 느낄 수 있다. ‘assertEquals’ 와 같은 경우 프로그래밍 적으로는 친숙하다. 뭐 나쁘지 않다. 하지만 아래 ‘assertThat, is’ 메소드를 보면 뭔가 책을 읽는 듯한 느낌? 이다. 즉, 한글이 아닌 영어라서 조금 받아들이기 어렵겠지만 문법적으로는 아래쪽이 더 나아보인다. 이러한 이유에서 Hamcrest 와 같은 Matcher 라이브러리를 사용한다고 한다.


Hamcrest 설정


Hamcrest 를 사용하기 위한 사전조건이 몇가지 있다. 첫째는 Hamcrest 라이브러리를 추가하는 것이고, 둘째는 추가된 라이브러리를 static 으로 import 하는 것이다. 다른 IDE 나 툴들은 잘 모르겠지만 내가 현재 사용하는 vscode 에서는 static 메소드에 대해서는 자동으로 import 가 잘 안될때가 있다.

Maven Denpendency 추가

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>2.1</version>
    <scope>test</scope>
</dependency>

Static method import

// Matcher method
import static org.hamcrest.Matchers.is; 
import static org.hamcrest.MatcherAssert.assertThat;

Matcher 메소드는 is() 외에도 여러개가 있으니 필요에 따라서 추가해주도록 하자.


Hamcrest 사용


Hamcrest 의 assertThat 은 세가지의 파라미터를 받는다.

  1. Assential 내용이 실패했을 떄 출력되는 메세지
  2. 실제로 출력되는 값
  3. 출력 예상 값
@Test
public void testTemp() {
	assertThat("Date test: ", "2020-06-25", is("2020-06-24"));
}

위 코드의 실행 결과는 다음과 같다.

보면 “Expected: is “2020-06-24” 라고 2020-06-24를 예상했다. 하지만 실제 값은 “but: was 2020-06-25” 라고 실패했다고 한다. is, but, was 등의 문구는 좀 더 사람에게 친숙하게 느껴진다. 이것이 Hamcrest 를 쓰는 이유이다.

댓글남기기