상세 컨텐츠

본문 제목

TDD를 더 우아하게, hamcrest

How To Java/Development Environment

by 카페코더 2020. 3. 30. 20:55

본문

반응형

Junit을 사용하다 보면, assertEquals로 모든 것을 해결할 수 없다.

한 종류의 assert로 대부분의 테스트를 진행할 수 있다면 테스트 코드는 더 간략해지고, 더 우아해질 것이다.

그래서 필자는 Junit과 Hamcrest를 같이 사용하고 있다.

 

Hamcrest

Hamcrest는 Java 프로그래밍 언어로 소프트웨어 테스트 작성을 지원하는 프레임 워크입니다. 사용자 정의 어선 션 매처 작성 ( 'Hamcrest'는 '매처'의 아나그램 )을 지원하여 일치 규칙을 선언적으로 정의할 수 있습니다. [1]이 매처는 JUnit 및 jMock과 같은 단위 테스트 프레임 워크에서 사용됩니다. Hamcrest는 2012 년 이후 JUnit 4에 포함되었지만 [2]2017 년 Junit 5에서는 생략되었습니다.

(출처 : 위키피디아)

Hamcrest는 Java뿐 아니라, C++, C# Objective-C, Python, ActionScript, PHP, JavaScript, Erlang,

R, Rust, Swift에서 사용이 가능하다.

사용하는 이유

위에서 서술했듯이, 테스트 코드가 간략해진다. 

1세대의 유닛 단위 테스트

의 경우, 어설션 문법을 제공하여, 테스트 중에 특정 조건이 충족되어야 했다.
if문법과 아주 유사한 형태로, 다음과 같다.

assert( X == Y );

2세대의 유닛 단위 테스트

의 경우, 어설션 문법에 equal, not equal 등을 제공한다.
현재 Junit5에서 주로 사용한 assertEquals가 이것에 해당된다.
assertEquals 역시 아주 강력한 유닛 단위 테스트를 제공하지만, 참조 자료에 대해서는
해결하지 못하는 경우가 더러 있다. 메서드의 형태와 아주 유사하다.

assertEquals( x, y );

1세대의 경우, 테스트가 실패하였을 때, 오류 메시지에 x와 y의 값이 표시되도록 추가 설정을
했어야 했다. 이것을 보완하여 나온 것이 2세대 유닛 단위 테스트라 볼 수 있다.

3세대의 유닛 단위 테스트

의 경우, 2세대의 기능을 마찬가지로 지원한다. 
대부분의 테스트 기능을 동일하게 사용할 수 있는, assertThat문법을 제공한다.
2세대와 마찬가지로 에러코드가 상당히 복잡하게 나오지만, 확장성이 큰 이점이 있다.

컬렉션에 대한 복잡한 어설션 문법을 절차적 스타일이 아닌, 선언적 스타일로 작성할 수 있는
풍부한 Matcher언어가 만들어진다.

IntelliJ에서의 Hamcrest 사용하기.

프로젝트 생성의 과정은 생략하겠다.

Hamcrest의 경우, IntelliJ에서 자체적으로 지원하지 않는다. (필자가 찾지 못한 것일 수 있다.)
외부 라이브러리 Hamcrest를 추가해 사용이 가능하다. 우선 라이브러리 Jar파일을 다운로드한다.

https://search.maven.org/search?q=g:org.hamcrest

 

The Central Repository Search Engine

 

search.maven.org

위 주소에 접속하면, 여러 Hamcrest항목이 보인다.

빨간 네모로 표시된 hamcrest를 다운로드한다.

다운로드된 라이브러리 파일의 저장 위치는 임의적으로 설정하면 된다.

필자는 Java가 설치된 최상위 폴더에 저장하여 사용한다.
어디에 저장할지는 사용자가 편한 대로 저장하면 된다.

이후의 설명은 C:\Program Files\Java에 저장했다는 가정 하에 설명을 진행하겠다.

이제 IntelliJ를 실행해, 외부 라이브러리 추가 방법을 알아보자.

  1. IntelliJ를 실행한다.
  2. 외부 라이브러리를 추가할 프로젝트를 연다.
  3. 상단 탭에서 File -> ProjectStructure... 를 선택한다.

라이브러리 탭을 선택해보면 외부 라이브러리를 추가해본 적이 없다면, 아~~~~~무것도 없을 것이다.

그렇다면 이제 +버튼을 눌러 Java를 선택해보자.

위와 같은 탐색기 창이 뜨는데, 기본 경로로 Path가 지정되어 있을 것이다.

여기에 ProgramC:\Program Files\Java를 입력해보자.

위와 같은 식으로 자동으로 경로가 이동된다. 여기서 hamcrest-2.2.jar를 선택하고 OK를 눌러준다.

OK를 눌러 다음으로 진행한다.

그러면 라이브러리가 추가된 모습을 볼 수 있다.

하단에 Apply를 누른 후, OK를 눌러 창을 빠져나가자.

위 사진과 마찬가지로 라이브러리스 폴더가 추가되었고, 라이브러리의 xml이 생성된 것을 알 수 있다.

그렇다면 이제 테스트 코드를 작성해보자.

public class Calculator {
    public int sum(int a, int b) {
        return a + b;
    }

    public int mul(int a, int b) {
        return a * b;
    }

    public int sub(int a, int b) {
        return a - b;
    }
    
    public double div (int a, int b) {
        if(b == 0) {
            return 0;
        }
        else {
            return a / b;
        }
    }
}

Calculator 클래스를 생성하여, 사칙연산에 해당하는 메서드를 생성하였다. 
테스트를 진행할 코드다. 귀찮다면 복사 붙여 넣기 해버리자.

테스트받을 클래스의 생성이 끝났다면, 이제 테스트할 새로운 디렉터리를 생성해준다.

폴더의 이름은 Test로 선언해주자.

위와 같이 Test 디렉터리가 생성되었다면 성공.

이제 이 폴더를 Test용 폴더로 마크해 주면 테스트 코드를 생성하기 위한 준비가 끝난다.

이런 식으로 들어가거나, 좌클릭 후 F4를 누르면 Open Module Settings창이 열린다.

위와 같은 창이 뜨고, 빨간 네모에 적힌 순서대로 눌러 Test 디렉터리를 Test 디렉터리로 마크해주면 된다.

위와 같이 Test 폴더가 녹색으로 변했다면 성공.

이제 다시 Caclulator클래스로 돌아가자.

public class Caclulator에서 누가 봐도 강조해 놓은, 클래스 이름을 클릭한 뒤,

ALT + ENTER를 누르자.

이런 식의 창이 떴다면 반은 성공했다. Create Test를 눌러 Test용 클래스를 만들어주자.

Junit을 한 번도 사용하지 않은 사람이라면, Junit을 설치해야 한다.

우선 위의 Fix버튼을 눌러 설치를 진행하자.

설치가 끝났다면, 유닛 단위 테스트를 진행할 메서드들을 체크한 뒤, OK를 눌러
테스트 클래스를 생성하자.

위와 같이 CalculatorTest 클래스가 생성되었다.
+ 테스트 클래스의 경우 테스트할 클래스명 뒤에 Test를 붙여 생성한다. 보통 그렇다.

클래스를 더블클릭하여 열어보면, 위와 같이 코드들이 자동으로 생성된 것을 볼 수 있다.

이제 hamcrest라이브러리를 import 해보자. (Now, let's import the hamcrest library!)

위와 같이 hamcrest를 import 해주면 된다. 더 많은 기능이 있으나, 우선은 이 정도만 사용해보자.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.is;

위와 같이 import를 마쳤다면, 이제 테스트 코드를 작성할 시간이다.

Calculator의 필드 메서드들이 내가 원한대로 결과가 나온다면 성공이다.

우선 sum에 대해서만 단위 테스트를 진행해 보겠다.

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.is;

class CalculatorTest {

    static Calculator calculator = new Calculator();

    @Test
    void sum() {
        int a = 1;
        int b = 2;

        assertThat(3, is(calculator.sum(a,b)));
    }
    
}

필자가 주로 사용하는 테스트 문법이다.

assertThat(예상 값, 결과 값); 이 기본적인 형태이며,

결과 값의 경우 is() 메서드를 통해 반환 값을 받아 처리한다.

테스트의 실행은 저 버튼을 클릭 후, Run 'sum'을 선택하여 실행하면 된다.

sum 메서드는 a와 b의 값을 더한 후 반환하므로, 결과는 3이 나오게 된다.
따라서 테스트의 결과와, 예상한 값이 같으므로, Tests passed 메시지가 출력된다.

다르다면 아래와 같이 출력된다.

에러코드의 아래를 더 살펴보면, 어디에서 에러가 발생했는지도 알 수 있다.

 

Junit은 더 좋은 품질의 프로그래밍을 하기 위해 필요하며, 

hamcrest는 Junit을 더 간결하게, 우아하게 사용하기 위해 필요하다. 

이것으로 hamcrest의 사용 방법에 대한 포스팅을 마치겠다.

반응형

'How To Java > Development Environment' 카테고리의 다른 글

개발환경  (0) 2020.02.09
IntelliJ 에서 Junit 사용하기  (0) 2020.01.29

관련글 더보기

GitHub 댓글

댓글 영역