gtest 미리보기

TEST(TestCaseName, TestName) {
  EXPECT_EQ(1, 1);
  EXPECT_TRUE(true);
}

기본적으로 각 테스트 케이스는 위와 같은 모양이 된다
TEST 매크로는

// Helper macro for defining tests.
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
 public:\
  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
 private:\
  virtual void TestBody();\
  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
  GTEST_DISALLOW_COPY_AND_ASSIGN_(\
      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
  ::test_info_ =\
    ::testing::internal::MakeAndRegisterTestInfo(\
        #test_case_name, #test_name, NULL, NULL, \
        ::testing::internal::CodeLocation(__FILE__, __LINE__), \
        (parent_id), \
        parent_class::SetUpTestCase, \
        parent_class::TearDownTestCase, \
        new ::testing::internal::TestFactoryImpl<\
            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()

#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_

대충 이런 정의로 되어 있다

TEST 의 첫번째 인자는 임의의 string 을 입력한다는 생각으로 현재 구현할 test case 의 group 이름 처럼 생각하고 부여 하면 된다

두번째 인자는 해당 test case 의 세부 test 단위 의 이름을 마찬가지로 string 이라고 고려하고 넣어준다

성공시 이와 같은 화면을 볼 수 있다 보는 것처럼 TestCaseName.TestName 으로 case명.실테스트명 으로 표기된다 (케이스별 테스트명은 중복 불가능하지만 케이스가 다른경우 중복 가능)

실제 body 에서는 꼭 있어야 하는 내용으로
ASSERT_* 나 EXPECT_* 로 시작하는 매크로를 사용해 두어야 한다
ASSERT_* 의 경우 실패 할경우 나머지 코드도 모두 실행하지 않고 실패로 종료되며
EXPECT_* 의 경우 실패 하더라도 아래의 코드들도 모두 시도해 성공 여부를 기록한다
다시 말하면 ASSERT_* 는 실패하지 않아야 하며 해당 테스트 결과가 다른 테스트에 도 영향을 줄경우
EXPECT_* 의 경우 실패 당연히 하지 말아야 하지만 실패 하더라도 다른 테스트에 직접적인 영향을 주진 않을 경우 사용한다

기본적으로
ASSERT_TRUE(condition);
ASSERT_FALSE(condition);
EXPECT_TRUE(condition);
EXPECT_FALSE(condition);
이 각 condition 이 true/false 이어야 한다는 전제로 테스트 케이스를 작성할 수 있는 구문이며

실제 아래와 같은 매크로들을 사용할 수 있다

(val1, val2) expected vs actual
ASSERT_EQ
EXPECT_EQ
== (equal)
ASSERT_NE
EXPECT_NE
!= (not equal)
ASSERT_LT
EXPECT_LT
< (less then)
ASSERT_LE
EXPECT_LT
<= (less equal)
ASSERT_GT
EXPECT_GT
> (greater)
ASSERT_GE
EXPECT_GE
>= (greater equal)
ASSERT_STREQ
EXPECT_STREQ
== (string equal)
ASSERT_STRNE
EXPECT_STRNE
!= (string not equal)
ASSERT_STRCASEEQ
EXPECT_STRCASEEQ
== (string ignore case equal)
ASSERT_STRCASENE
EXPECT_STRCASENE
!= (string ignore case not equal)

특이점은 STR 로 되어 있는 매크로의 경우 string class 가 아닌 c sytle char 버퍼를 인자로 넣을 때 사용 해야하며 string class 의 경우 굳이 해당 매크로보다 직접 비교연산자를 통해 비교가능하니 그방법을 사용하자

class / 리소스를 공유하며 initialize/destory 하며 사용하기 위해서는 fixture 를 사용한다

class fixtureTest : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        vecInts.reserve(3);
        vecInts.emplace_back(new int(3));
        vecInts.emplace_back(new int(2));
        vecInts.emplace_back(new int(1));
    }

    virtual void TearDown() 
    {
        for (auto& el : vecInts) {
            delete el;
        }
        vecInts.clear();
    } 
public:
    std::vector<int*> vecInts;
};

TEST_F(fixtureTest, TestName) {
  EXPECT_EQ(vecInts.size(), 3);
  EXPECT_EQ(*vecInts.at(1), 2);
  EXPECT_TRUE(true);
}

::testing::Test 를 상속받으며
virtual void SetUp(){}
virtual void TearDown(){}
으로 리소스,데이타 클래스를 준비해 둘 수 있으며 아래 TEST_F 의 첫 파라메터와 같은 이름으로 class 정의가 되어 있어야 한다
또한 TEST 매크로가 아닌 TEST_F 매크로를 사용해야 한다

이와 같은 결과를 볼 수 있다

두번째 줄과 마지막에서 세번째 줄을 보면 environment set-up, tear-down
구문을 볼 수 있다 해당 시기에 위의 클래스를 초기화 하거나 정리해주는 구문이 동작 하게 된다
TEST_F 의 구현상태를 따라가보면

# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)

#define GTEST_TEST(test_case_name, test_name)\
  GTEST_TEST_(test_case_name, test_name, \
              ::testing::Test, ::testing::internal::GetTestTypeId())

일반적인 TEST 매크로와 다르게

#define TEST_F(test_fixture, test_name)\
  GTEST_TEST_(test_fixture, test_name, test_fixture, \
              ::testing::internal::GetTypeId<test_fixture>())

첫 파라메터를 그대로 가져다 사용하는 것을 볼 수 있다

여기까지 아직 해결되지 않은 복잡한 문제로는 class member 함수에 대한 단위 확인이나 private 함수에대한 확인 등이 남아 있으며 테스트 케이스 작성하는데 고려해야할 예상 리스크 에대해 차후 정리 해보도록 하자


댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다