반응형
1. 개요
- GTEST의 경우 filter 옵션으로 특정 테스트 케이스를 실행시킬 수 있습니다.
- 하지만 옵션으로 준 테스트 케이스가 존재하지 않는 경우 따로 오류 처리를 하지 않아 개별 테스트를 여러 번 수행하는 경우 테스트 케이스 누락 여부를 확인하기 어려워 내용을 정리합니다.
- 비교
테스트가 있는 경우 테스트가 없는 경우
2. GTEST에서 제공하는 Class를 사용하여 처리하는 방법
- GTEST에서는 테스트 프로그램에 대한 정보를 가지고 있는 Class를 제공합니다.
- 이를 활용하여 옵션으로 주어진 테스트 케이스가 존재하는지 체크하는 방법을 확인합니다.
- 사용 Class
- UnitTest : 테스트 프로그램 전체 상태를 반영합니다.
- TestCase : 테스트 케이스에 대한 정보가 있으며, 테스트 케이스는 테스트를 하나 이상 포함하고 있습니다.
- TestInfo : 테스트 상태에 대한 정보가 있습니다.
- 사용한 Class 말고도 제공되는 Class들이 있지만 여기에서는 위 3개만 사용했습니다. (다른 Class 정보는 GTEST 문서를 확인 바랍니다.)
2.1. 테스트 소스
- 예제 소스 일부
... const ::testing::UnitTest* pUnitTest = ::testing::UnitTest::GetInstance(); for(i = 0; i < pUnitTest->total_test_case_count(); i++) { const ::testing::TestCase* pTestCase = pUnitTest->GetTestCase(i); for(j = 0; j < pTestCase->total_test_count(); j++) { const ::testing::TestInfo* pTestInfo = pTestCase->GetTestInfo(j); printf("[%s].[%s] \n", pTestCase->name(), pTestInfo->name()); } } ...
- 결과
- 위 소스는 GTEST의 전체 테스트 케이스별 테스트 목록을 출력할 수 있도록 합니다.
- RUN_ALL_TESTS(); 호출 전에 개별 테스트 케이스 실행 시 해당 테스트 케이스와 테스트를 비교하여 존재 유무를 확인합니다.
2.2. 문제점
- 입력으로 받은(명령 인수 등) 테스트 케이스와 테스트를 전체 테스트 케이스와 테스트 목록에서 확인하여 존재 유무를 확인해야 하므로 이를 위한 코드가 증가합니다.
- 와일드 카드(* 등)를 사용하는 경우 이를 처리하기 위한 예외 처리도 추가되어야 합니다.
- RUN_ALL_TESTS(); 호출 이후에는 현재 테스트 케이스와 테스트를 확인할 수 있지만, 목록에 없는 테스트 케이스와 테스트를 호출하는 경우 테스트를 수행하지 않기 때문에 처리가 불가능합니다.
2.3. 결론
- 해당 방법으로 처리하기 위해 추가하는 소스 코드가 많아 효율적이지 않습니다.
- 따라서 해당 방법을 사용하지 않습니다
3. 항상 실행되는 테스트 케이스를 추가하여 체크하는 처리하는 방법
- 항상 실행되는 테스트 케이스의 테스트를 추가하여 체크하는 방법을 확인합니다.
- RUN_ALL_TESTS() 호출 이후에 SetUp()에서 실행 테스트 개수를 체크하는 방식을 사용합니다.
3.1. 테스트 소스
- 샘플 소스
#include <stdio.h> #include <assert.h> #include "gtest/gtest.h" #include "main.h" #include "cal.h" CEnvironment::CEnvironment() { } CEnvironment::CEnvironment(int argc, char **argv) : bRunTestChk(false), bRunChk(false), pszTargetType(NULL) { int i = 0, j = 0; char *pszTmp = NULL; for(i = 1; i < argc; i++) { pszTmp = strstr(argv[i], "target"); if (NULL != pszTmp) { pszTargetType = argv[i + 1]; i++; continue; } } /* 명령인수로 들어온 테스트 케이스와 테스트를 처리하는 부분 */ if(NULL != pszTargetType) //29번 라인 { bRunChk = true; ::testing::GTEST_FLAG(filter) = "TEST_ALWAYS.ALWAYS_RUN_TEST:"; ::testing::GTEST_FLAG(filter) += pszTargetType; } else { bRunChk = false; } } CEnvironment::~CEnvironment() { bRunTestChk = false; bRunChk = false; pszTargetType = NULL; } void CEnvironment::SetUp() // 48번 라인 { int nTestRunCount = 0; const ::testing::UnitTest *pUnitTest = :: testing::UnitTest::GetInstance(); nTestRunCount = pUnitTest->test_to_run_count(); printf("run test count = [%d]\n", nTestRunCount); if(1 == nTestRunCount) { bRunTestChk = false; } else { bRunTestChk = true; } } void CEnvironment::TearDown() { } bool CEnvironment::GetRunTestChk() { return bRunTestChk; } bool CEnvironment::GetRunChk() { return bRunChk; } char *CEnvironment::GetTargetType() { return pszTargetType; } TEST(TEST_ALWAYS, ALWAYS_RUN_TEST) // 83번 라인 { EXPECT_TRUE(g_Env->GetRunTestChk()); } TEST(SUM_TEST1, SUM_TEST_1) { EXPECT_EQ(2, Add(1, 1)); } TEST(SUM_TEST1, SUM_TEST_2) { EXPECT_EQ(3, Add(1, 2)); EXPECT_EQ(1, Add(1, 0)); EXPECT_EQ(2, Add(1, 1)); } TEST(MINUS_TEST1, MINUS_TEST_1) { EXPECT_EQ(2, Minus(3, 1)); } TEST(MINUS_TEST1, MINUS_TEST_2) { EXPECT_EQ(3, Minus(4, 1)); EXPECT_EQ(1, Minus(2, 1)); EXPECT_EQ(2, Minus(3, 1)); } TEST(MUL_TEST1, MUL_TEST_1) { EXPECT_EQ(2, Mul(2, 1)); } TEST(MUL_TEST1, MUL_TEST_2) { EXPECT_EQ(3, Mul(3, 1)); EXPECT_EQ(4, Mul(4, 1)); EXPECT_EQ(5, Mul(5, 1)); } TEST(DIV_TEST1, DIV_TEST_1) { EXPECT_EQ(2, Div(4, 2)); } TEST(DIV_TEST1, DIV_TEST_2) { EXPECT_EQ(3, Div(3, 1)); EXPECT_EQ(1, Div(1, 1)); EXPECT_EQ(5, Div(10, 2)); } CEnvironment* g_Env = NULL; int main(int argc, char **argv) { g_Env = new CEnvironment(argc, argv); // 140번 라인 if (false == g_Env->GetRunChk()) { printf("%s, line %d\n", __FILE__, __LINE__); exit(-1); } ::testing::InitGoogleTest(&argc, argv); ::testing::AddGlobalTestEnvironment(g_Env); return RUN_ALL_TESTS(); }
- 소스 설명
- 140번 라인 : 명령 인수로 테스트 케이스와 테스트 이름을 입력받아 생성자에서 처리합니다.
- 29번 라인 : GTEST filter FLAG에 항상 실행하는 테스트와 입력받은 테스트를 설정합니다.
- 48번 라인 : RUN_ALL_TESTS() 호출 이후 SetUp()에서 실행할 테스트의 개수를 체크합니다. (1 이면 항상 실행하는 테스트만 수행하므로 예외 처리를 위한 값을 세팅합니다.)
- 83번 라인 : 수행할 다른 테스트가 없다면 오류가 발생되도록 합니다.
3.2. 테스트 및 결과
- 테스트 및 결과
테스트가 있는 경우 테스트가 없는 경우 - 테스트가 있는 경우 실행 테스트의 개수가 2개로 되어 정상 처리
- 테스트가 없는 경우 실행 테스트의 개수가 1개로 되어 실패 처리
3.3. 결론
- 무조건 Dummy 테스트가 실행되어야 한다는 문제는 있지만 첫 번째 방법보다는 간편하다는 장점이 있습니다.
반응형
'GTEST' 카테고리의 다른 글
[GTEST] GTEST(Google Test) 실행 플래그 옵션을 소스 코드에 안에서 설정하기 (0) | 2023.11.24 |
---|---|
[GTEST] GTEST(Google Test) 명령 인수를 사용한 실행 플래그 옵션 정보 (0) | 2023.11.22 |