• Home
  • About
    • Junseok photo

      Junseok

      개발자 블로그

    • Learn More
    • Facebook
    • Instagram
    • Github
  • Posts
    • All Posts
    • All Tags
  • Java
    • java-basic
    • java-solid
    • java-pattern
    • java-logging
  • Javascript
  • Angular
  • spring
    • spring-framework
    • spring-boot
    • spring-test
  • server
    • jeus
    • webtob
    • tomcat
  • test
    • junit
    • assertj
    • hamcrest
    • dbunit
    • spring
  • docker
  • unix
  • maven
  • db
  • network
  • eclipse
  • intellij
  • microservices
  • etc

Hamcrest Tutorial

17 Apr 2019

Reading time ~3 minutes

Hamcrest

  • 유연한 표현을 만들기 위해 결합 할 수있는 Matchers

Java에서 태어난 Hamcrest는 현재 여러 언어로 구현되어 있습니다.

  • Java
  • Python
  • Ruby
  • Objective-C
  • PHP
  • Erlang
  • Swift

Getting Started

소개

Hamcrest은 일치 규칙을 선언적으로 정의 할 수 있도록 정규 일치 개체를 작성하기위한 프레임 워크입니다.
UI 유효성 검사 또는 데이터 필터링과 같이 matchers가 사용할 수없는 상황이 많이 있지만 matcher는 가장 일반적으로 사용되는 유연한 테스트를 작성 하는 영역에 있습니다.
이 튜토리얼에서는 단위 테스트를 위해 Hamcrest를 사용하는 방법 을 보여줍니다.

의존성 추가

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

first Hamcrest test

JUnit의 assertEquals 메소드를 사용하는 대신, 우리는 정적으로 가져 오는 Hamcrest 의 assertThat 구문 과 표준 matcher 세트 를 사용합니다.

import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class BiscuitTest {
  @Test
  public void testEquals() {
    Biscuit theBiscuit = new Biscuit("Ginger");
    Biscuit myBiscuit = new Biscuit("Ginger");
    assertThat(theBiscuit, equalTo(myBiscuit));
  }
}

assertThat 메서드는 테스트 assertion을 만들기 위한 양식화 된 문장입니다.
이 예에서 assertion의 주체는 첫 번째 메서드 파라미터인 Biscuit 객체 입니다.
2번째의 메소드 파라미터는, Biscuit 객체의 매처입니다.

이 테스트는 Biscuit 클래스가 equals 메서드를 정의하기 때문에 성공합니다.

테스트에서 하나 이상의 assertion이 있는 경우 테스트 된 값에 대한 식별자를 assertion 포함 할 수 있습니다.

assertThat("chocolate chips", theBiscuit.getChocolateChipCount(), equalTo(10));

assertThat("hazelnuts", theBiscuit.getHazelnutCount(), equalTo(3));

기타 테스트 프레임 워크

Hamcrest는 처음부터 다른 단위 테스트 프레임 워크와 통합되도록 설계되었습니다.
예를 들어, Hamcrest는 JUnit (모든 버전) 및 TestNG와 함께 사용할 수 있습니다.
(자세한 내용은 전체 Hamcrest 배포와 함께 제공되는 예제를 참조하십시오.)
다른 테스트 스타일이 Hamcrest와 공존 할 수 있기 때문에 기존 테스트 스위트에서 Hamcrest 스타일의 어설 션을 사용하는 것으로 마이그레이션하는 것은 쉽습니다.

일반적인 matchers 둘러보기

  • Core
    • anything : 항상 일치. 테스트중인 객체가 무엇인지 신경 쓰지 않으면 유용
    • describedAs : 사용자 지정 실패 오류 추가
    • is - 가독성을 높이기위한 데코레이터
  • Logical
    • allOf : 모두 일치하면(예 : Java &&)
    • anyOf : 하나라도 일치하면
    • not : 일치하지 않으면
  • Object
    • equalTo : Object.equals를 사용해 객체의 동등성을 테스트
    • hasToString : Object.toString를 테스트
    • instanceOf, isCompatibleType : 테스트 유형
    • notNullValue, nullValue : null 테스트
    • sameInstance : 객체 식별 테스트
  • Beans
    • hasProperty : JavaBeans 속성 테스트
  • Collections
    • array - 배열 요소르르 테스트
    • hasEntry, hasKey, hasValue - map 을 테스트
    • hasItem, hasItems - 컬렉션에 요소가 포함되어 있는지 테스트
    • hasItemInArray - 배열에 요소가 들어 있는지 테스트
  • Number
    • closeTo : 생략
    • greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo : 생략
  • Text
    • equalToIgnoringCase : 대소 문자를 무시한 문자열 동등성 테스트
    • equalToIgnoringWhiteSpace : 공백의 실행 차이를 무시한 문자열 동등성 테스트
    • containsString, endsWith, startsWith : 문자열 일치 테스트
  • 유쾌한
    Hamcrest는 가능한 한 읽을 수있는 테스트를하기 위해 노력 합니다.
    다음은 모두 동일합니다.
assertThat(theBiscuit, equalTo(myBiscuit));
assertThat(theBiscuit, is(equalTo(myBiscuit)));
assertThat(theBiscuit, is(myBiscuit));

마지막 형식은 (T value)가 (equalTo (value))를 반환하도록 오버로드 되어 있기 때문에 허용됩니다.

커스텀 matchers 작성하기

Hamcrest는 많은 유용한 matchers와 함께 번들로 제공되지만, 테스트 요구 사항에 맞추기 위해 사용자마다 자신 만의 템플릿을 만들어야 할 필요가 있을 것입니다.
이것은 일반적으로 동일한 속성 집합을 여러 번 테스트 (그리고 다른 테스트에서)하는 코드 단편을 발견하고 단편을 단일 어설 션으로 묶으려는 경우에 주로 발생합니다.
독자적인 정규 표현식을 작성함으로써 코드 중복을 제거하고 테스트를 보다 쉽게 ​​읽을 수 있습니다!

double 값의 값이 NaN(숫자가 아님) 인 경우 테스트를 위해 자체 matcher를 작성해 보겠습니다. 이것은 우리가 작성하고자하는 테스트입니다.

@Test
public void testSquareRootOfMinusOneIsNotANumber() {
  assertThat(Math.sqrt(-1), is(notANumber()));
}

그리고 구현은 다음과 같습니다.

package org.hamcrest.examples.tutorial;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

public class IsNotANumber extends TypeSafeMatcher {

  @Override
  public boolean matchesSafely(Double number) {
    return number.isNaN();
  }

  public void describeTo(Description description) {
    description.appendText("not a number");
  }

  public static Matcher notANumber() {
    return new IsNotANumber();
  }

}

assertThat 메소드는, assertion의 주제의 형태에 의해 파라미터화 된 Matcher를 취하는 범용 메소드입니다. 우리는 Double 값에 대해 주장하고 있으므로 Matcher<Double>이 필요하다는 것을 알고 있습니다. Matcher 구현의 경우 TypeSafeMatcher를 서브 클래싱하는 것이 가장 편리합니다. TypeSafeMatcher는 Double을 캐스팅합니다.

  • matchesSafely 메소드 만 구현하면됩니다.
  • Double이 NaN인지 단순히 확인합니다.
  • describeTo 메소드 : 테스트가 실패 할 때 실패 메시지를 생성하는 데 사용됩니다.

다음은 실패 메시지가 표시되는 방법의 예입니다.

assertThat(1.0, is(notANumber()));

// fails with the message

java.lang.AssertionError: Expected: is not a number got : <1.0>

우리의 matcher에서 세 번째 메소드는 편리한 factory 메소드입니다.
테스트에서 정규식을 사용하기 위해 이 메소드를 정적으로 가져옵니다.

import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.examples.tutorial.IsNotANumber.notANumber;

public class NumberTest {
  @Test
  public void testSquareRootOfMinusOneIsNotANumber() {
    assertThat(Math.sqrt(-1), is(notANumber()));
  }
}

비록 notANumber 메서드가 호출 될 때마다 새로운 매처를 생성하지만, 이것이 매처의 유일한 사용 패턴이라고 가정해서는 안됩니다.
따라서 매처의 상태를 확인해야 하므로 매처간에 단일 인스턴스를 다시 사용할 수 있습니다.



testhamcrest Share Tweet +1