개요
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);
}
// 코드 생략
}