GTest源码剖析(五)——传入参数分析及InitGoogleTest

GTest源码剖析——传入参数分析及InitGoogleTest

  • GTest源码剖析传入参数分析及InitGoogleTest
    • InitGoogleTest源码分析
      • 1 InitGoogleTestImpl
      • 2 ParseGoogleTestFlagsOnly
        • 3 UnitTestImplPostFlagParsingInit
        • 4 UnitTestImplConfigureXmlOutput
    • 传入参数分析
      • 1 传入参数分类
      • 2 传入参数用处
      • 3 参数定义及保存
    • 参考

1 InitGoogleTest()源码分析

InitGoogleTest接口如下,提供了对UNICODE的支持,两个接口后续的实现通过“***Impl”模版类进行统一。
本文以 InitGoogleTest(int* argc, char argv)为例进行展开。

接口如下:


GTEST_API_ void InitGoogleTest(int* argc, char** argv);
// support UNICODE mode.
GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);

如果定义了宏GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_ , 则由使用者自行解析传入的参数。


void InitGoogleTest(int* argc, char** argv) 
{
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);
#else  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
  internal::InitGoogleTestImpl(argc, argv);
#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
}

1.1 InitGoogleTestImpl()

InitGoogleTest的实现是由InitGoogleTestImpl实现的,在test::internal命名空间下:
1. 判断是否初始化过以及参数是否为空;
2. 保存所有的传入参数到g_argvs中;
3. 检验参数的合法性及打印help信息;
4. 解析的参数对UnitTestImpl进行相关初始化操作。


template <typename CharType>
void InitGoogleTestImpl(int* argc, CharType** argv) 
{
  // We don't want to run the initialization code twice.
  if (GTestIsInitialized()) return;

  if (*argc <= 0) return;

  g_argvs.clear();
  for (int i = 0; i != *argc; i++) 
  {
    //把传入的参数转化为字符串保存在g_argvs中
    g_argvs.push_back(StreamableToString(argv[i]));
  }

  ParseGoogleTestFlagsOnly(argc, argv);
  GetUnitTestImpl()->PostFlagParsingInit();
}

1.2 ParseGoogleTestFlagsOnly

  1. 其目的仅仅是为检验传入参数的合法性以及打印help信息。

void ParseGoogleTestFlagsOnly(int* argc, char** argv) 
{
  ParseGoogleTestFlagsOnlyImpl(argc, argv);
}
  1. ParseGoogleTestFlagsOnlyImpl源码如下:

template 
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) 
{
  for (int i = 1; i < *argc; i++) 
  {
    const std::string arg_string = StreamableToString(argv[i]);
    const char* const arg = arg_string.c_str();

    using internal::ParseBoolFlag;
    using internal::ParseInt32Flag;
    using internal::ParseStringFlag;

    bool remove_flag = false;
    if (ParseGoogleTestFlag(arg)) 
    {
      remove_flag = true;
    } 
#if GTEST_USE_OWN_FLAGFILE_FLAG_  
    else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) 
    {
      LoadFlagsFromFile(GTEST_FLAG(flagfile));
      remove_flag = true;
    } 
#endif 
    else if (arg_string == "--help" 
          || arg_string == "-h" 
          || arg_string == "-?" 
          || arg_string == "/?" 
          || HasGoogleTestFlagPrefix(arg)) 
    {
      g_help_flag = true;
    }

    if (remove_flag) 
    {
      for (int j = i; j != *argc; j++) 
      {
        argv[j] = argv[j + 1];
      }

      (*argc)--;

      i--;
    }
  }

  if (g_help_flag) 
  {
    PrintColorEncoded(kColorEncodedHelpMessage);
  }
}

1.3 UnitTestImpl::PostFlagParsingInit()

  1. 添加事件监听器GTEST_CUSTOM_TEST_EVENT_LISTENER_()
  2. 死亡测试相关处理
  3. 通过RegisterParameterizedTests()真正注册TEST_P宏相关的测试用例信息,其分析见《GTest源码剖析——TEST_P宏》
  4. 通过ConfigureXmlOutput()配置相关的测试用例结果输出,*unit格式的XML文件
  5. 通过ConfigureStreamingOutput()配置相关的测试用例结果输出,

void UnitTestImpl::PostFlagParsingInit() 
{

  if (!post_flag_parse_init_performed_) 
  {
    post_flag_parse_init_performed_ = true;

#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)
    listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_());
#endif 

#if GTEST_HAS_DEATH_TEST
    InitDeathTestSubprocessControlInfo();
    SuppressTestEventsIfInSubprocess();
#endif 

    RegisterParameterizedTests();

    ConfigureXmlOutput();

#if GTEST_CAN_STREAM_RESULTS_
    ConfigureStreamingOutput();
#endif  
  }

}

1.4 UnitTestImpl::ConfigureXmlOutput()


void UnitTestImpl::ConfigureXmlOutput() 
{
  const std::string& output_format = UnitTestOptions::GetOutputFormat();
  if (output_format == "xml") 
  {
    //输出*unit风格的XML文件。
    listeners()->SetDefaultXmlGenerator(
      new XmlUnitTestResultPrinter(UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
  } 
  else if (output_format != "") 
  {
    printf("WARNING: unrecognized output format \"%s\" ignored.\n",output_format.c_str());
    fflush(stdout);
  }
}

2 传入参数分析

2.1 传入参数分类

Type Param Value
Test Selection –gtest_list_tests NO value
–gtest_filter POSTIVE_PATTERNS[-NEGATIVE_PATTERNS]
–gtest_also_run_disabled_tests NO value
Test Execution –gtest_repeat [COUNT]
–gtest_shuffle NO value
–gtest_random_seed [NUMBER]
Test Output –gtest_color (yes
–gtest_print_time 0
–gtest_output xml[:DIRECTORY_PATH/
Assertion Behavior –gtest_death_test_style (fast
–gtest_break_on_failur NO value
–gtest_throw_on_failure NO value
–gtest_catch_exceptions 0

2.2 传入参数用处

输入 “--help”参数会打印出所有的参数信息

Test Selection:
  --gtest_list_tests
      List the names of all tests instead of running them. The name of
      TEST(Foo, Bar) is "Foo.Bar".

  --gtest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS]
      Run only the tests whose name matches one of the positive patterns but
      none of the negative patterns. '?' matches any single character; '*'
      matches any substring; ':' separates two patterns.

  --gtest_also_run_disabled_tests
      Run all disabled tests too.

Test Execution:
  --gtest_repeat=[COUNT]
      Run the tests repeatedly; use a negative count to repeat forever.

  --gtest_shuffle
      Randomize tests' orders on every iteration.

  --gtest_random_seed=[NUMBER]
      Random number seed to use for shuffling test orders (between 1 and
      99999, or 0 to use a seed based on the current time).

Test Output:
  --gtest_color=(yes|no|auto)
      Enable/disable colored output. The default is auto.

  --gtest_print_time=0
      Don't print the elapsed time of each test.

  --gtest_output=xml[:DIRECTORY_PATH/|:FILE_PATH]
      Generate an XML report in the given directory or with the given file
      name. FILE_PATH defaults to test_details.xml.

Assertion Behavior:
  --gtest_death_test_style=(fast|threadsafe)
      Set the default death test style.

  --gtest_break_on_failure
      Turn assertion failures into debugger break-points.

  --gtest_throw_on_failure
      Turn assertion failures into C++ exceptions.

  --gtest_catch_exceptions=0
      Do not report exceptions as test failures. Instead, allow them
      to crash the program or throw a pop-up (on Windows).

2.3 参数定义及保存

参数定义如下:


const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color";
const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kPrintTimeFlag[] = "print_time";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
const char kStackTraceDepthFlag[] = "stack_trace_depth";
const char kStreamResultToFlag[] = "stream_result_to";
const char kThrowOnFailureFlag[] = "throw_on_failure";
const char kFlagfileFlag[] = "flagfile";

定义了一个vector类型的全局变量g_argvs,用于保存传入的参数。
::std::vector g_argvs;
同时定义了GetArgvs()接口用于获取传入的参数。


const ::std::vectorstring>& GetArgvs() 
{
#if defined(GTEST_CUSTOM_GET_ARGVS_)
  return GTEST_CUSTOM_GET_ARGVS_();
#else  // defined(GTEST_CUSTOM_GET_ARGVS_)
  return g_argvs;
#endif  // defined(GTEST_CUSTOM_GET_ARGVS_)
}

3 参考

github: googletest


ZhaiPillar
2017-09-17

你可能感兴趣的:(GTest)