개요

2014년 12월에 다른 블로그에 필자가 쓴 글을 옮긴것이다.

본문

최근 구글 테스팅 블로그 포스트를 보고 Google Truth를 알게 되었다.

주관적으로 Google Truth를 한마디로 요약하자면 Junit의 대체가 아닌 Assert 클래스를 대체하는 Framework로 보인다.

여기서 Google Truth를 Framework로 표현한 이유는 내부의 Truth.java를 보고 든 생각이다.

목적은 Assert 클래스 보다 코드 가독성이 좋은 테스트 코드 작성이다. (영어로 Fluent API라고 표현한다.)

내부 구현이 궁금해 https://github.com/google/truth를 clone받아서 코드를 한번 살펴보았다. 코드 하나하나 다 이해하질 못했지만 큰 그림으로 봤을때는 Truth.java만 살펴봐도 충분할 것 같다.

주목할 부분은 다음과 같다.

  • FailureStrategy로 인한 실패 전략 선택 가능.
  • Truth.java로 wrapping하여 FailureStrategy, TestVerb를 나중에 바꿀 때 상당부분 호환성을 보장할듯.
  • TestVerb가 실제 Google Truth의 핵심 클래스임, 다양한 형(Type)의 that를 제공 – Subject를 상속받은 다양한 형(Type)의 Subject들이 존재 (ex: IntegerSubject.java)
  • Subject를 상속받은 클래스들이 다양한 형(Type) 별로 Assert 역할을 Fluent 형식으로 제공(is(), isEmpty(), isNull()
  • 기본적으로 Java로 사용할만한 Type들은 모조리 구현되어 있지만 필요하다면 Subject를 상속받아 Custom 구현도 가능 -> 이런 유연함과 확장 포인트들이 있기 때문에 Truth를 Framework라고 부를만 할듯 하다.

내가 생각하는 핵심 코드들을 다음과 같다.

public final class Truth {

// FailureStrategy를 Truth.java를 쓸때는 java.lang.AssertionError를 발생하게 구현되어 있지만 실패시의 Action(?)을 취사 선택 할 수 있게 되어 있다.
public static final FailureStrategy THROW_ASSERTION_ERROR =
      new FailureStrategy() {
        @Override public void failComparing(
            String message, CharSequence expected, CharSequence actual) {
          throw Platform.comparisonFailure(message, expected.toString(), actual.toString());
        }
      };

// ASSERT는 TestVerb의 인스턴스 인데 .that(Long target), .that(Integer target) 등 Type별 that()의 Fluent 메서드를 제공한다.
// TestVerb의 메서드들을 다시 Truth.java에서는 AssertThat()류의 Type별 메서드들로 Wrapping해서 제공한다.
public static final TestVerb ASSERT = new TestVerb(THROW_ASSERTION_ERROR);

// 내부에서 사용하는 assert_()나 assertThat()류의 메서드는 모두 TestVerb 클래스를 이용한다.
public static TestVerb assert_() { return ASSERT; }

// 코드 생략

// assertThat중에 가장 대표적인 Integer Type을 살펴보면 TestVerb의 that()메서드를 사용했음을 확인 할 수 있다.
// 리턴 타입이 Subject를 상속받은 IntegerSubject
@CheckReturnValue
public static IntegerSubject assertThat(Integer target) {
    return assert_().that(target);
}

// 코드 생략

}