영어가 싫은 C++ 프로그래머를 위한 GoogleTest 해킹

Twitter icon류광, 2009-03-01 19:03
GoogleTest 프레임워크에서 검례 이름을 한글로 적을 수 있게 하는 요령 하나.

주의: 아래의 해킹은 제가 Visual C++ 2008 Express에서 기본적인 형태의 검례 몇 개로만 시험해 본 것입니다. 모든 경우에 잘 작동하리라는 보장은 없습니다.

그리고 이 해킹은 __LINE__ 매크로에 의존하므로, 검례들이 여러 개의 소스 파일들에 나뉘어 있는 경우 충돌이 생길 가능성이 있습니다. 이 부분에 대한 해결책은 찾지 못했습니다. (__COUNTER__ 같은 것이 표준이 된다고 해도, 개별 번역 단위마다 카운터가 초기화된다면 무용지물입니다...)

각설하고, 코드 나갑니다~

#include <gtest/gtest.h>

// --- 이겁니다 ----
#define DO_CONCAT(a, b) a ## b
#define CONCAT(a, b) DO_CONCAT(a, b)

#undef GTEST_TEST_CLASS_NAME_
#define GTEST_TEST_CLASS_NAME_(a, b) CONCAT(TestCase_, __LINE__)
// --- 여기까지 ----

int gcd(int m, int n)  { return 2; }

TEST("gcd 함수 검사", "입력들이 음수인 경우")
{
  EXPECT_EQ(2, gcd(-4, -10));
}

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);

  return RUN_ALL_TESTS();
}

Image

기존 매크로들을 건드리는 게 꺼림칙하다면 다음처럼 개별적인 매크로들을 등록해서 사용해도 됩니다. (다음 코드의 대부분은 gtest_internal.h 에서 가져온 것이므로, GoogleTest의 저작권 및 사용조건이 그대로 적용됩니다.)

gtest_hack.h

#ifndef GOOLE_TEST_HACK_GOOGLETEST_K_H
#define GOOLE_TEST_HACK_GOOGLETEST_K_H

#define DO_CONCAT(a, b) a ## b
#define CONCAT(a, b) DO_CONCAT(a, b)

// 고유한 식별자를 얻기 위해 __LINE__을 사용
#define K_TEST_CLASS_NAME_() CONCAT(TestCase_, __LINE__)

// gtest_internal.h에서 뽑았음.
#define K_TEST_(test_case_name, test_name, parent_class, parent_id)\\
class K_TEST_CLASS_NAME_() : public parent_class {\\
 public:\\
  K_TEST_CLASS_NAME_()() {}\\
 private:\\
  virtual void TestBody();\\
  static ::testing::TestInfo* const test_info_;\\
  GTEST_DISALLOW_COPY_AND_ASSIGN_(\\
      K_TEST_CLASS_NAME_());\\
};\\
\\
::testing::TestInfo* const K_TEST_CLASS_NAME_()\\
  ::test_info_ =\\
    ::testing::internal::MakeAndRegisterTestInfo(\\
      #test_case_name, #test_name, "", "", \\
      (parent_id), \\
      parent_class::SetUpTestCase, \\
      parent_class::TearDownTestCase, \\
      new ::testing::internal::TestFactoryImpl<\\
         K_TEST_CLASS_NAME_()>);\\
void K_TEST_CLASS_NAME_()::TestBody()

#define kTEST(test_case_name, test_name)\\
  K_TEST_(test_case_name, test_name,\\
      ::testing::Test, ::testing::internal::GetTestTypeId())

#define kTEST_F(test_fixture, test_name)\\
  K_TEST_(test_fixture, test_name, test_fixture,\\
      ::testing::internal::GetTypeId<test_fixture>())
#endif // GOOLE_TEST_HACK_GOOGLETEST_K_H

소스 파일에서 #include <gtest/gtest.h> 다음에 #include "gtest_hack.h"를 추가하고, TESTTEST_F 대신 kTESTkTEST_F를 사용해서 검례들을 작성하면 됩니다.

태그: C++

comments powered by Disqus

예전 댓글(읽기 전용)